Date: Thu Feb 27 13:12:41 2020
Scientist: Ran Yin
Sequencing (Waksman): Dibyendu Kumar
Statistics: Davit Sargsyan
Principal Investigator: Ah-Ng Kong
# Taxonomic Ranks:
# **K**ing **P**hillip **C**an n**O**t **F**ind **G**reen **S**ocks
# * Kingdom
# * Phylum
# * Class
# * Order
# * Family
# * Genus
# * Species
```r
# options(stringsAsFactors = FALSE,
# scipen = 999)
# # Increase mmemory size to 64 Gb----
# invisible(utils::memory.limit(65536))
# str(knitr::opts_chunk$get())
# # NOTE: the below does not work!
# knitr::opts_chunk$set(echo = FALSE,
# message = FALSE,
# warning = FALSE,
# error = FALSE)
# require(knitr)
# require(kableExtra)
require(phyloseq)
<!-- rnb-source-end -->
<!-- rnb-output-begin eyJkYXRhIjoiTG9hZGluZyByZXF1aXJlZCBwYWNrYWdlOiBwaHlsb3NlcVxuIn0= -->
Loading required package: phyloseq
<!-- rnb-output-end -->
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxuIyByZXF1aXJlKHNoaW55KVxucmVxdWlyZShkYXRhLnRhYmxlKVxuYGBgXG5gYGAifQ== -->
```r
```r
# require(shiny)
require(data.table)
<!-- rnb-source-end -->
<!-- rnb-output-begin eyJkYXRhIjoiTG9hZGluZyByZXF1aXJlZCBwYWNrYWdlOiBkYXRhLnRhYmxlXG5kYXRhLnRhYmxlIDEuMTIuMiB1c2luZyAxOCB0aHJlYWRzIChzZWUgP2dldERUdGhyZWFkcykuICBMYXRlc3QgbmV3czogci1kYXRhdGFibGUuY29tXG4ifQ== -->
Loading required package: data.table data.table 1.12.2 using 18 threads (see ?getDTthreads). Latest news: r-datatable.com
<!-- rnb-output-end -->
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxucmVxdWlyZShnZ3Bsb3QyKVxuYGBgXG5gYGAifQ== -->
```r
```r
require(ggplot2)
<!-- rnb-source-end -->
<!-- rnb-output-begin eyJkYXRhIjoiTG9hZGluZyByZXF1aXJlZCBwYWNrYWdlOiBnZ3Bsb3QyXG4ifQ== -->
Loading required package: ggplot2
<!-- rnb-output-end -->
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxucmVxdWlyZShwbG90bHkpXG5gYGBcbmBgYCJ9 -->
```r
```r
require(plotly)
<!-- rnb-source-end -->
<!-- rnb-output-begin eyJkYXRhIjoiTG9hZGluZyByZXF1aXJlZCBwYWNrYWdlOiBwbG90bHlcblxuQXR0YWNoaW5nIHBhY2thZ2U6IMOi4oKsy5xwbG90bHnDouKCrOKEolxuXG5UaGUgZm9sbG93aW5nIG9iamVjdCBpcyBtYXNrZWQgZnJvbSDDouKCrMuccGFja2FnZTpnZ3Bsb3Qyw6LigqzihKI6XG5cbiAgICBsYXN0X3Bsb3RcblxuVGhlIGZvbGxvd2luZyBvYmplY3QgaXMgbWFza2VkIGZyb20gw6LigqzLnHBhY2thZ2U6c3RhdHPDouKCrOKEojpcblxuICAgIGZpbHRlclxuXG5UaGUgZm9sbG93aW5nIG9iamVjdCBpcyBtYXNrZWQgZnJvbSDDouKCrMuccGFja2FnZTpncmFwaGljc8Oi4oKs4oSiOlxuXG4gICAgbGF5b3V0XG4ifQ== -->
Loading required package: plotly
Attaching package: ‘plotly’
The following object is masked from ‘package:ggplot2’:
last_plot
The following object is masked from ‘package:stats’:
filter
The following object is masked from ‘package:graphics’:
layout
<!-- rnb-output-end -->
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxucmVxdWlyZShEVClcbmBgYFxuYGBgIn0= -->
```r
```r
require(DT)
<!-- rnb-source-end -->
<!-- rnb-output-begin eyJkYXRhIjoiTG9hZGluZyByZXF1aXJlZCBwYWNrYWdlOiBEVFxuIn0= -->
Loading required package: DT
<!-- rnb-output-end -->
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxucmVxdWlyZShsbWVyVGVzdClcbmBgYFxuYGBgIn0= -->
```r
```r
require(lmerTest)
<!-- rnb-source-end -->
<!-- rnb-output-begin eyJkYXRhIjoiTG9hZGluZyByZXF1aXJlZCBwYWNrYWdlOiBsbWVyVGVzdFxuTG9hZGluZyByZXF1aXJlZCBwYWNrYWdlOiBsbWU0XG5Mb2FkaW5nIHJlcXVpcmVkIHBhY2thZ2U6IE1hdHJpeFxuXG5BdHRhY2hpbmcgcGFja2FnZTogw6LigqzLnGxtZXJUZXN0w6LigqzihKJcblxuVGhlIGZvbGxvd2luZyBvYmplY3QgaXMgbWFza2VkIGZyb20gw6LigqzLnHBhY2thZ2U6bG1lNMOi4oKs4oSiOlxuXG4gICAgbG1lclxuXG5UaGUgZm9sbG93aW5nIG9iamVjdCBpcyBtYXNrZWQgZnJvbSDDouKCrMuccGFja2FnZTpzdGF0c8Oi4oKs4oSiOlxuXG4gICAgc3RlcFxuIn0= -->
Loading required package: lmerTest Loading required package: lme4 Loading required package: Matrix
Attaching package: ‘lmerTest’
The following object is masked from ‘package:lme4’:
lmer
The following object is masked from ‘package:stats’:
step
<!-- rnb-output-end -->
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxuc291cmNlKFxcc291cmNlL2Z1bmN0aW9uc19tYXkyMDE5LlJcXClcbiMgT24gV2luZG93cyBzZXQgbXVsdGl0aHJlYWQ9RkFMU0UtLS0tXG5tdCA8LSBUUlVFXG5gYGBcbmBgYCJ9 -->
```r
```r
source(\source/functions_may2019.R\)
# On Windows set multithread=FALSE----
mt <- TRUE
<!-- rnb-source-end -->
<!-- rnb-chunk-end -->
<!-- rnb-text-begin -->
# Introduction
C57BL/6 wild-type (WT) and Nrf-2 double-knock-out (KO -/-) mice were given 2-week microbiome stabilization process using AIN93M diet and 8 more weeks to treat with either AIN93M or AIN93M 5% PEITC diet. Fecal samples were collected weekly, immediately frozen in liquid nitrogen and stored at -80^o^C. Serum, cecal, colon epithelial and whole colon tissues at week 10 were also collected for further analyses. Baseline, week 1 and 4 fecal samples were selected for 16s rRNA sequencing.
This document examines results from the WT mice samples.
We will attampt to answer the following questions:
1. Did microbiome change over time?
2. Was microbiome affected by diet?
3. Was there a difference between the KO and WT?
4. If there was a change in microbiome composition, what functional changes did it carry? What are the essential functions of the bacteria affected by the treatment and how can this be shown in vivo (metabolites, inflammation markers, etc.)?
# Data preprocessing
## Raw Data
FastQ files were downloaded from [this Rutgers Box location](https://rutgers.app.box.com/folder/90143462291). A total of 144 files (2 per sample, pair-ended) and a pair of undetermined reads were downloaded.
## Script
This script (***nrf2ubiome_dada2_sep2019_v1.Rmd***) was developed using [DADA2 Pipeline Tutorial (1.12)](https://benjjneb.github.io/dada2/tutorial.html) with tips and tricks from the [University of Maryland Shool of Medicine Institute for Genome Sciences (IGS)](http://www.igs.umaryland.edu/) [Microbiome Analysis Workshop (April 8-11, 2019)](http://www.igs.umaryland.edu/education/wkshp_metagenome.php). The output of the DADA2 script (***data_may2019/ps_sep2019.RData***) is explored in this document.
# Meta data: sample description
<!-- rnb-text-end -->
<!-- rnb-chunk-begin -->
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuIyBMb2FkIGRhdGEtLS0tXG4jIENvdW50c1xubG9hZChcImRhdGFfc2VwMjAxOS9wc19zZXAyMDE5LlJEYXRhXCIpXG5cbiMgVGF4b25vbXlcbmxvYWQoXCJkYXRhX3NlcDIwMTkvdGF4YS5SRGF0YVwiKVxudGF4YSA8LSBkYXRhLnRhYmxlKHNlcTE2cyA9IHJvd25hbWVzKHRheGEpLFxuICAgICAgICAgICAgICAgICAgIHRheGEpXG5gYGAifQ== -->
```r
# Load data----
# Counts
load("data_sep2019/ps_sep2019.RData")
# Taxonomy
load("data_sep2019/taxa.RData")
taxa <- data.table(seq16s = rownames(taxa),
taxa)
NOTE: correction to the meta-data! (11/15/2019)
correct_samples <- fread("data_sep2019/16s metadata Sep-2019.csv")
ps_sep2019@sam_data$DSS <- correct_samples$DSS
Samples
ps_sep2019@sam_data$Genotype_Week <- paste(ps_sep2019@sam_data$genotype,
ps_sep2019@sam_data$time,
sep = "_")
ps_sep2019@sam_data$ID <- factor(paste0(ps_sep2019@sam_data$mice_num,
ps_sep2019@sam_data$cage))
ps_sep2019@sam_data$TREATMENT <- paste0(ps_sep2019@sam_data$DSS,
ps_sep2019@sam_data$PEITC,
ps_sep2019@sam_data$cranberry)
ps_sep2019@sam_data$TREATMENT <- factor(ps_sep2019@sam_data$TREATMENT,
levels = c("000",
"100",
"110",
"101"),
labels = c("Naive",
"DSS",
"DSS+PEITC",
"DSS+Cranberry"))
samples <- ps_sep2019@sam_data
datatable(samples,
options = list(pageLength = nrow(samples)))
Prune data
The OTUs were mapped to Bacteria (96.07%), Eukaryota (2.95%) and Archea (0.03%) kingdoms, and 75 OTUs (0.95%) undefined.
The total of 7,867 unique sequences were found. Out of those, 7,558 were mapped to bacterial genomes.
dim(ps_sep2019@otu_table@.Data)
[1] 72 7867
# Remove OTU not mapped to Bacteria
ps0 <- subset_taxa(ps_sep2019,
Kingdom == "Bacteria")
dim(ps0@otu_table@.Data)
[1] 72 7558
Out of the 7,558 OTUs 7,247 belonged to 12 Phyla. 311 of the OTUs (or 4.11% of bacterial OTUs) could not be mapped to a phylum.
t2 <- data.table(table(tax_table(ps0)[, "Phylum"],
exclude = NULL))
t2$V1[is.na(t2$V1)] <- "Unknown"
setorder(t2, -N)
t2[, pct := N/sum(N)]
setorder(t2, -N)
colnames(t2) <- c("Phylum",
"Number of OTUs",
"Percent of OTUs")
datatable(t2,
rownames = FALSE,
caption = "Number of Bacterial OTUs by Phylum",
class = "cell-border stripe",
options = list(search = FALSE,
pageLength = nrow(t2))) %>%
formatCurrency(columns = 2,
currency = "",
mark = ",",
digits = 0) %>%
formatPercentage(columns = 3,
digits = 2)
OTU table (first 10 rows)
Total counts per sample (i.e. sequencing depth)
t1 <- colSums(otu[, 7:ncol(otu)])
t1 <- data.table(SAMPLE_NAME = names(t1),
Total = t1)
t2 <- data.table(SAMPLE_NAME = rownames(samples),
ID = samples$ID,
CAGE = samples$cage,
TREATMENT = samples$TREATMENT,
Genotype = samples$genotype,
WEEK = samples$time)
smpl <- merge(t1,
t2,
by = "SAMPLE_NAME")
p1 <- ggplot(smpl,
aes(x = SAMPLE_NAME,
y = Total,
fill = TREATMENT,
colour = WEEK)) +
facet_wrap(~ Genotype,
scale = "free_x") +
geom_bar(stat = "identity") +
scale_x_discrete("") +
scale_y_continuous("Number of Reads") +
scale_fill_discrete("Treatment") +
theme(axis.text.x = element_text(angle = 45,
hjust = 1))
ggplotly(p1)
Richness (Alpha diversity)
Shannon index (aka Shannon enthrophy) is calculated as:
H’ = -sum(1 to R)p(i)ln(p(i)) When there is exactly 1 type of data (e.g. a single species in the sample), H’=0. The opposite scenario is when there are R>1 species present in the sample in the exact same amounts and H’=ln(R).
Shannon’s diversity index was calculated for each sample and ploted over time using the 7,764 from the 13 Phylum above.
shannon.ndx <- estimate_richness(ps0,
measures = "Shannon")
shannon.ndx <- data.table(SAMPLE_NAME = rownames(shannon.ndx),
shannon.ndx)
smpl <- merge(smpl,
shannon.ndx,
by = "SAMPLE_NAME")
p1 <- ggplot(smpl,
aes(x = Total,
y = Shannon,
fill = Genotype,
shape = WEEK)) +
geom_point(size = 2) +
scale_shape_manual(breaks = unique(smpl$WEEK),
values = 21:23)
tiff(filename = "tmp/shannon_vs_depth.tiff",
height = 5,
width = 6,
units = "in",
res = 600,
compression = "lzw+p")
print(p1)
graphics.off()
ggplotly(p1)

Even though estimate_richness function does not adjust for the sequencing depth, there is no correlation between the index and the sample’s sequecing depth. Proceed with the comparison.
Shannon idex over time
p1 <- plot_richness(ps0,
x = "time",
measures = "Shannon") +
facet_wrap(~ genotype) +
geom_line(aes(group = ID),
color = "black") +
geom_point(aes(fill = TREATMENT),
shape = 21,
size = 3,
color = "black") +
scale_x_discrete("") +
theme(axis.text.x = element_text(angle = 30,
hjust = 1,
vjust = 1))
ggplotly(p = p1,
tooltip = c("ID",
"value"))
p1 <- p1 +
scale_fill_discrete("") +
theme(legend.position = "top")
tiff(filename = "tmp/shannon.tiff",
height = 4,
width = 5,
units = "in",
res = 600,
compression = "lzw+p")
print(p1)
graphics.off()
The plot above suggests that the largest differences in alpha diversity (as measured by Shannon’s index) are in genotype.
Test if the richness changed between the baseline and Week 8.
smpl$TREATMENT <- factor(smpl$TREATMENT,
levels = c("DSS",
"Naive",
"DSS+PEITC",
"DSS+Cranberry"))
tmp <- droplevels(smpl[WEEK != "week1"])
m1 <- lm(Shannon ~ WEEK*(TREATMENT + Genotype),
# offset = Total,
data = tmp)
summary(m1)
Call:
lm(formula = Shannon ~ WEEK * (TREATMENT + Genotype), data = tmp)
Residuals:
Min 1Q Median 3Q Max
-0.316186 -0.091027 0.007886 0.110704 0.293230
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 5.94987 0.07064 84.233 < 2e-16
WEEKweek8 0.01158 0.09989 0.116 0.9084
TREATMENTNaive 0.14581 0.08935 1.632 0.1109
TREATMENTDSS+PEITC -0.03923 0.08935 -0.439 0.6631
TREATMENTDSS+Cranberry -0.22582 0.08935 -2.527 0.0158
Genotypewidetype -0.54156 0.06318 -8.572 2.06e-10
WEEKweek8:TREATMENTNaive 0.01181 0.12636 0.093 0.9261
WEEKweek8:TREATMENTDSS+PEITC 0.01652 0.12636 0.131 0.8966
WEEKweek8:TREATMENTDSS+Cranberry 0.21535 0.12636 1.704 0.0965
WEEKweek8:Genotypewidetype 0.23085 0.08935 2.584 0.0137
(Intercept) ***
WEEKweek8
TREATMENTNaive
TREATMENTDSS+PEITC
TREATMENTDSS+Cranberry *
Genotypewidetype ***
WEEKweek8:TREATMENTNaive
WEEKweek8:TREATMENTDSS+PEITC
WEEKweek8:TREATMENTDSS+Cranberry .
WEEKweek8:Genotypewidetype *
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.1548 on 38 degrees of freedom
Multiple R-squared: 0.7845, Adjusted R-squared: 0.7335
F-statistic: 15.37 on 9 and 38 DF, p-value: 3.671e-10
m2 <- lmer(Shannon ~ WEEK*(TREATMENT + Genotype) + (1 | ID),
# offset = Total,
data = tmp)
summary(m2)
Linear mixed model fit by REML. t-tests use Satterthwaite's method [
lmerModLmerTest]
Formula: Shannon ~ WEEK * (TREATMENT + Genotype) + (1 | ID)
Data: tmp
REML criterion at convergence: -22.2
Scaled residuals:
Min 1Q Median 3Q Max
-1.53721 -0.47495 0.06753 0.44489 1.53874
Random effects:
Groups Name Variance Std.Dev.
ID (Intercept) 0.01259 0.1122
Residual 0.01136 0.1066
Number of obs: 48, groups: ID, 24
Fixed effects:
Estimate Std. Error df t value
(Intercept) 5.94987 0.07064 29.76837 84.233
WEEKweek8 0.01158 0.06879 19.00000 0.168
TREATMENTNaive 0.14581 0.08935 29.76837 1.632
TREATMENTDSS+PEITC -0.03923 0.08935 29.76837 -0.439
TREATMENTDSS+Cranberry -0.22582 0.08935 29.76837 -2.527
Genotypewidetype -0.54156 0.06318 29.76837 -8.572
WEEKweek8:TREATMENTNaive 0.01181 0.08701 19.00000 0.136
WEEKweek8:TREATMENTDSS+PEITC 0.01652 0.08701 19.00000 0.190
WEEKweek8:TREATMENTDSS+Cranberry 0.21535 0.08701 19.00000 2.475
WEEKweek8:Genotypewidetype 0.23085 0.06152 19.00000 3.752
Pr(>|t|)
(Intercept) < 2e-16 ***
WEEKweek8 0.86814
TREATMENTNaive 0.11322
TREATMENTDSS+PEITC 0.66379
TREATMENTDSS+Cranberry 0.01704 *
Genotypewidetype 1.55e-09 ***
WEEKweek8:TREATMENTNaive 0.89350
WEEKweek8:TREATMENTDSS+PEITC 0.85139
WEEKweek8:TREATMENTDSS+Cranberry 0.02291 *
WEEKweek8:Genotypewidetype 0.00135 **
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Correlation of Fixed Effects:
(Intr) WEEKw8 TREATMENTN TREATMENTDSS+P
WEEKweek8 -0.487
TREATMENTNv -0.632 0.308
TREATMENTDSS+P -0.632 0.308 0.500
TREATMENTDSS+C -0.632 0.308 0.500 0.500
Gentypwdtyp -0.447 0.218 0.000 0.000
WEEK8:TREATMENTN 0.308 -0.632 -0.487 -0.243
WEEK8:TREATMENTDSS+P 0.308 -0.632 -0.243 -0.487
WEEK8:TREATMENTDSS+C 0.308 -0.632 -0.243 -0.243
WEEKwk8:Gnt 0.218 -0.447 0.000 0.000
TREATMENTDSS+C Gntypw WEEK8:TREATMENTN
WEEKweek8
TREATMENTNv
TREATMENTDSS+P
TREATMENTDSS+C
Gentypwdtyp 0.000
WEEK8:TREATMENTN -0.243 0.000
WEEK8:TREATMENTDSS+P -0.243 0.000 0.500
WEEK8:TREATMENTDSS+C -0.487 0.000 0.500
WEEKwk8:Gnt 0.000 -0.487 0.000
WEEK8:TREATMENTDSS+P WEEK8:TREATMENTDSS+C
WEEKweek8
TREATMENTNv
TREATMENTDSS+P
TREATMENTDSS+C
Gentypwdtyp
WEEK8:TREATMENTN
WEEK8:TREATMENTDSS+P
WEEK8:TREATMENTDSS+C 0.500
WEEKwk8:Gnt 0.000 0.000
Calculate change in Shannon index from baseline
dd <- smpl
dd[, delta := Shannon - Shannon[WEEK == "baseline"],
by = ID]
dd$diff <- paste(dd$WEEK,
"-baseline",
sep = "")
dd <- dd[WEEK != "baseline",]
p1 <- ggplot(dd,
aes(x = TREATMENT,
y = delta,
fill = Genotype)) +
facet_wrap(~ diff) +
geom_hline(yintercept = 0,
linetype = "dashed") +
geom_point(position = position_dodge(0.3),
shape = 21,
size = 3) +
scale_y_continuous("Shannon Index Percent Change from Baseline") +
theme(axis.text.x = element_text(angle = 45,
hjust = 1))
print(p1)

dd$TREATMENT <- factor(dd$TREATMENT,
levels = c("DSS",
"Naive",
"DSS+PEITC",
"DSS+Cranberry"))
dd$Genotype <- factor(dd$Genotype,
levels = c("widetype",
"nrf2KO"))
m1 <- lm(delta ~ TREATMENT*Genotype,
data = dd)
summary(m1)
Call:
lm(formula = delta ~ TREATMENT * Genotype, data = dd)
Residuals:
Min 1Q Median 3Q Max
-0.40513 -0.09560 -0.02012 0.09568 0.35517
Coefficients:
Estimate Std. Error t value
(Intercept) 0.25142 0.07286 3.451
TREATMENTNaive -0.04426 0.10303 -0.430
TREATMENTDSS+PEITC -0.15777 0.10303 -1.531
TREATMENTDSS+Cranberry 0.04463 0.10303 0.433
Genotypenrf2KO -0.18412 0.10303 -1.787
TREATMENTNaive:Genotypenrf2KO -0.02851 0.14571 -0.196
TREATMENTDSS+PEITC:Genotypenrf2KO 0.24747 0.14571 1.698
TREATMENTDSS+Cranberry:Genotypenrf2KO 0.07927 0.14571 0.544
Pr(>|t|)
(Intercept) 0.00133 **
TREATMENTNaive 0.66985
TREATMENTDSS+PEITC 0.13358
TREATMENTDSS+Cranberry 0.66720
Genotypenrf2KO 0.08153 .
TREATMENTNaive:Genotypenrf2KO 0.84586
TREATMENTDSS+PEITC:Genotypenrf2KO 0.09721 .
TREATMENTDSS+Cranberry:Genotypenrf2KO 0.58946
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.1785 on 40 degrees of freedom
Multiple R-squared: 0.249, Adjusted R-squared: 0.1176
F-statistic: 1.894 on 7 and 40 DF, p-value: 0.09608
# No significant interactions, proceed with 2-way analysis
m2 <- lm(delta ~ TREATMENT + Genotype,
data = dd)
summary(m2)
Call:
lm(formula = delta ~ TREATMENT + Genotype, data = dd)
Residuals:
Min 1Q Median 3Q Max
-0.49158 -0.09742 -0.01290 0.11101 0.35281
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.21414 0.05849 3.661 0.000683 ***
TREATMENTNaive -0.05851 0.07399 -0.791 0.433377
TREATMENTDSS+PEITC -0.03404 0.07399 -0.460 0.647813
TREATMENTDSS+Cranberry 0.08427 0.07399 1.139 0.261014
Genotypenrf2KO -0.10956 0.05232 -2.094 0.042176 *
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.1812 on 43 degrees of freedom
Multiple R-squared: 0.1674, Adjusted R-squared: 0.08999
F-statistic: 2.162 on 4 and 43 DF, p-value: 0.08947
At Week 8 there was significantly smaller increase of alpha diversity from baseline in Nrf2 KO compared to WT, and in DSS+Cranberry compared to DSS only.
Load aminoacids
aa <- fread("data_sep2019/sep2019_aminoacids.csv")
aa <- aa[!is.na(ID), ]
aa$ID <- paste0(aa$ID,
aa$CAGE)
smpl1 <- unique(smpl[, c("ID",
"TREATMENT",
"Genotype")])
smpl1$ID <- as.character(smpl1$ID)
aa <- merge(smpl1,
aa,
by = "ID")
aa[, trt_week := paste(TREATMENT,
WEEK,
sep = "_")]
aa$trt_week <- factor(aa$trt_week,
levels = c("Naive_week2",
"Naive_week6",
"DSS_week2",
"DSS_week6",
"DSS+Cranberry_week2",
"DSS+Cranberry_week6" ,
"DSS+PEITC_week2",
"DSS+PEITC_week6"))
for (i in 8:(ncol(aa) - 1)) {
tmp <- aa[, c(1, 3, 7, ncol(aa), i), with = FALSE]
colnames(tmp)[5] <- "Y"
p1 <- ggplot(tmp,
aes(x = trt_week,
y = Y,
fill = Genotype,
group = ID)) +
geom_line(position = position_dodge(0.3)) +
geom_point(shape = 21,
size = 3,
position = position_dodge(0.3)) +
scale_x_discrete("") +
scale_y_continuous(colnames(aa)[i]) +
theme(axis.text.x = element_text(angle = 45,
hjust = 1))
# tiff(filename = paste0("tmp/",
# colnames(aa)[i],
# ".tiff"),
# height = 4,
# width = 5,
# units = "in",
# res = 600,
# compression = "lzw+p")
# print(p1)
# graphics.off()
print(p1)
}




















Aminoacid data PCA
dt_pca <- aa[, Alanine:glutamine]
m1 <- prcomp(dt_pca)
summary(m1)
Importance of components:
PC1 PC2 PC3 PC4 PC5 PC6
Standard deviation 4.8108 2.5833 1.78182 1.13495 0.93367 0.84949
Proportion of Variance 0.6276 0.1810 0.08609 0.03493 0.02364 0.01957
Cumulative Proportion 0.6276 0.8086 0.89466 0.92959 0.95323 0.97280
PC7 PC8 PC9 PC10 PC11 PC12
Standard deviation 0.62035 0.49052 0.35960 0.26786 0.22940 0.20322
Proportion of Variance 0.01044 0.00652 0.00351 0.00195 0.00143 0.00112
Cumulative Proportion 0.98323 0.98976 0.99326 0.99521 0.99663 0.99775
PC13 PC14 PC15 PC16 PC17 PC18
Standard deviation 0.1486 0.13250 0.11932 0.11154 0.08896 0.07274
Proportion of Variance 0.0006 0.00048 0.00039 0.00034 0.00021 0.00014
Cumulative Proportion 0.9983 0.99883 0.99922 0.99955 0.99977 0.99991
PC19 PC20
Standard deviation 0.05110 0.02565
Proportion of Variance 0.00007 0.00002
Cumulative Proportion 0.99998 1.00000
# Select PC-s to pliot (PC1 & PC2)
choices <- 1:2
# Scores, i.e. points (df.u)
dt.scr <- data.table(m1$x[, choices])
# Add grouping variable
dt.scr$grp <- aa$trt_week
dt.scr$TREATMENT <- aa$TREATMENT
dt.scr$WEEK <- aa$WEEK
dt.scr
# Loadings, i.e. arrows (df.v)
dt.rot <- as.data.frame(m1$rotation[, choices])
dt.rot$feat <- rownames(dt.rot)
dt.rot <- data.table(dt.rot)
dt.rot
dt.load <- melt.data.table(dt.rot,
id.vars = "feat",
measure.vars = 1:2,
variable.name = "pc",
value.name = "loading")
dt.load$feat <- factor(dt.load$feat,
levels = unique(dt.load$feat))
# Plot loadings
p0 <- ggplot(data = dt.load,
aes(x = feat,
y = loading)) +
facet_wrap(~ pc,
nrow = 2) +
geom_bar(stat = "identity") +
ggtitle("PC Loadings") +
theme(plot.title = element_text(hjust = 0.5),
axis.text.x = element_text(angle = 45,
hjust = 1))
tiff(filename = "tmp/pc.1.2_loadings.tiff",
height = 5,
width = 8,
units = 'in',
res = 300,
compression = "lzw+p")
print(p0)
graphics.off()
print(p0)

# Axis labels
u.axis.labs <- paste(colnames(dt.rot)[1:2],
sprintf('(%0.1f%% explained var.)',
100*m1$sdev[choices]^2/sum(m1$sdev^2)))
u.axis.labs
[1] "PC1 (62.8% explained var.)" "PC2 (18.1% explained var.)"
# Based on Figure p0, keep only a few variables with high loadings in PC1 and PC2----
# var.keep.ndx <- which(dt.rot$feat %in% c(...))
# Or select all
# var.keep.ndx <- 3:ncol(dt1)
# Use dt.rot[var.keep.ndx,] and dt.rot$feat[var.keep.ndx]
p1 <- ggplot(data = dt.rot,
aes(x = PC1,
y = PC2)) +
coord_equal() +
geom_point(data = dt.scr,
aes(fill = grp),
shape = 21,
size = 2,
alpha = 0.5) +
geom_segment(aes(x = 0,
y = 0,
xend = 10*PC1,
yend = 10*PC2),
arrow = arrow(length = unit(1/2, 'picas')),
size = 1.2,
color = "black") +
geom_text(aes(x = 11*PC1,
y = 11*PC2,
label = dt.rot$feat),
# size = 5,
hjust = 0.5) +
scale_x_continuous(u.axis.labs[1]) +
scale_y_continuous(u.axis.labs[2]) +
scale_fill_discrete(name = "Group") +
ggtitle("Biplot of Aminoacids") +
theme(plot.title = element_text(hjust = 0.5,
size = 20))
tiff(filename = "tmp/aminoacids_biplot.tiff",
height = 10,
width = 10,
units = 'in',
res = 300,
compression = "lzw+p")
print(p1)
graphics.off()
ggplotly(p1)

p2 <- ggplot(data = dt.rot,
aes(x = PC1,
y = PC2)) +
coord_equal() +
geom_point(data = dt.scr,
aes(fill = WEEK),
shape = 21,
size = 2,
alpha = 0.5) +
geom_segment(aes(x = 0,
y = 0,
xend = 10*PC1,
yend = 10*PC2),
arrow = arrow(length = unit(1/2, 'picas')),
size = 1.2,
color = "black") +
geom_text(aes(x = 11*PC1,
y = 11*PC2,
label = dt.rot$feat),
# size = 5,
hjust = 0.5) +
scale_x_continuous(u.axis.labs[1]) +
scale_y_continuous(u.axis.labs[2]) +
scale_fill_discrete(name = "Week") +
ggtitle("Biplot of Aminoacids") +
theme(plot.title = element_text(hjust = 0.5,
size = 20))
tiff(filename = "tmp/aminoacids_by_week_biplot.tiff",
height = 10,
width = 10,
units = 'in',
res = 300,
compression = "lzw+p")
print(p2)
graphics.off()
ggplotly(p2)

p2 <- ggplot(data = dt.rot,
aes(x = PC1,
y = PC2)) +
coord_equal() +
geom_point(data = dt.scr,
aes(fill = TREATMENT),
shape = 21,
size = 2,
alpha = 0.5) +
geom_segment(aes(x = 0,
y = 0,
xend = 10*PC1,
yend = 10*PC2),
arrow = arrow(length = unit(1/2, 'picas')),
size = 1.2,
color = "black") +
geom_text(aes(x = 11*PC1,
y = 11*PC2,
label = dt.rot$feat),
# size = 5,
hjust = 0.5) +
scale_x_continuous(u.axis.labs[1]) +
scale_y_continuous(u.axis.labs[2]) +
scale_fill_discrete(name = "Treatment") +
ggtitle("Biplot of Aminoacids") +
theme(plot.title = element_text(hjust = 0.5,
size = 20))
tiff(filename = "tmp/aminoacids_by_trt_biplot.tiff",
height = 10,
width = 10,
units = 'in',
res = 300,
compression = "lzw+p")
print(p2)
graphics.off()
ggplotly(p2)

Remove unmapped OTUs
The 311 unmapped OTUs were removed from further analysis (with 7,247 OTUs left).
ps1 <- subset_taxa(ps0,
!is.na(Phylum))
dim(ps1@otu_table@.Data)
[1] 72 7247
Counts at Phylum level
Relative abundance (%) at Phylum level
Remove phyla with relative abundance of >= 1% in less than 10% of samples.
t1 <- data.table(Phylum = ra_p$Phylum,
`Number of Samples` = rowSums(ra_p[, 2:ncol(ra_p)] >= 0.01))
t1$`Percent Samples` <- t1$`Number of Samples`/72
setorder(t1, -`Number of Samples`)
datatable(t1,
rownames = FALSE,
caption = "Taxonomic count table",
class = "cell-border stripe",
options = list(search = FALSE,
pageLength = nrow(t1))) %>%
formatPercentage(columns = 3,
digits = 1)
We will remove Chlamydiae from this analysis.
XX OTUs, down from YY OTUs in the previous table.
Relative Abundance in Samples at Different Taxonomic Ranks
1. Class
mu$Trt_Genotype <- factor(paste(mu$Treatment,
mu$Genotype,
sep = "_"))
p0 <- ggplot(mu,
aes(x = Week,
y = x,
group = Trt_Genotype)) +
facet_wrap(~ Class,
scale = "free_y") +
geom_line(position = position_dodge(0.3)) +
geom_point(aes(fill = Trt_Genotype),
shape = 21,
size = 2,
alpha = 0.5,
position = position_dodge(0.3)) +
scale_x_discrete("") +
scale_y_continuous("Relative Abundance (%)") +
theme(legend.position = "top",
axis.text.x = element_text(angle = 45,
hjust = 1))
tiff(filename = "tmp/wt_class_over_time.tiff",
height = 5,
width = 7,
units = "in",
res = 600,
compression = "lzw+p")
print(p0)
graphics.off()
print(p0)
p1 <- ggplot(mu,
aes(x = x,
y = Class,
color = Trt_Genotype,
shape = Week)) +
geom_point(size = 3,
alpha = 0.5) +
geom_vline(xintercept = 1,
linetype = "dashed") +
scale_x_continuous("Relative Abundance (%)") +
theme(legend.position = "top")
tiff(filename = "tmp/wt_class_ra.tiff",
height = 4,
width = 7,
units = "in",
res = 600,
compression = "lzw+p")
print(p1)
graphics.off()
ggplotly(p1)
2. Order
mu$Trt_Genotype <- factor(paste(mu$Treatment,
mu$Genotype,
sep = "_"))
p0 <- ggplot(mu,
aes(x = Week,
y = x,
group = Trt_Genotype)) +
facet_wrap(~ Order,
scale = "free_y") +
geom_line(position = position_dodge(0.3)) +
geom_point(aes(fill = Trt_Genotype),
shape = 21,
size = 2,
alpha = 0.5,
position = position_dodge(0.3)) +
scale_x_discrete("") +
scale_y_continuous("Relative Abundance (%)") +
theme(legend.position = "top",
axis.text.x = element_text(angle = 45,
hjust = 1))
tiff(filename = "tmp/wt_Order_over_time.tiff",
height = 5,
width = 7,
units = "in",
res = 600,
compression = "lzw+p")
print(p0)
graphics.off()
print(p0)
p1 <- ggplot(mu,
aes(x = x,
y = Order,
color = Trt_Genotype,
shape = Week)) +
geom_point(size = 3,
alpha = 0.5) +
geom_vline(xintercept = 1,
linetype = "dashed") +
scale_x_continuous("Relative Abundance (%)") +
theme(legend.position = "top")
tiff(filename = "tmp/wt_Order_ra.tiff",
height = 4,
width = 7,
units = "in",
res = 600,
compression = "lzw+p")
print(p1)
graphics.off()
ggplotly(p1)
3. Family
NOTE: only the first 24 families had large enough counts - ploting only them.
mu$Trt_Genotype <- factor(paste(mu$Treatment,
mu$Genotype,
sep = "_"))
mu1 <- droplevels(mu[Family %in% levels(mu$Family)[nlevels(mu$Family):(nlevels(mu$Family) - 24)], ])
p0 <- ggplot(mu1,
aes(x = Week,
y = x,
group = Trt_Genotype)) +
facet_wrap(~ Family,
scale = "free_y") +
geom_line(position = position_dodge(0.3)) +
geom_point(aes(fill = Trt_Genotype),
shape = 21,
size = 2,
alpha = 0.5,
position = position_dodge(0.3)) +
scale_x_discrete("") +
scale_y_continuous("Relative Abundance (%)") +
theme(legend.position = "top",
axis.text.x = element_text(angle = 45,
hjust = 1))
tiff(filename = "tmp/wt_Family_over_time.tiff",
height = 7,
width = 9,
units = "in",
res = 600,
compression = "lzw+p")
print(p0)
graphics.off()
print(p0)
p1 <- ggplot(mu1,
aes(x = x,
y = Family,
color = Trt_Genotype,
shape = Week)) +
geom_point(size = 3,
alpha = 0.5) +
geom_vline(xintercept = 1,
linetype = "dashed") +
scale_x_continuous("Relative Abundance (%)") +
theme(legend.position = "top")
tiff(filename = "tmp/wt_Family_ra.tiff",
height = 4,
width = 7,
units = "in",
res = 600,
compression = "lzw+p")
print(p1)
graphics.off()
ggplotly(p1)
4. Genus
mu$Trt_Genotype <- factor(paste(mu$Treatment,
mu$Genotype,
sep = "_"))
mu1 <- droplevels(mu[Genus %in% levels(mu$Genus)[nlevels(mu$Genus):(nlevels(mu$Genus) - 35)], ])
p0 <- ggplot(mu1,
aes(x = Week,
y = x,
group = Trt_Genotype)) +
facet_wrap(~ Genus,
scale = "free_y") +
geom_line(position = position_dodge(0.3)) +
geom_point(aes(fill = Trt_Genotype),
shape = 21,
size = 2,
alpha = 0.5,
position = position_dodge(0.3)) +
scale_x_discrete("") +
scale_y_continuous("Relative Abundance (%)") +
theme(legend.position = "top",
axis.text.x = element_text(angle = 45,
hjust = 1))
tiff(filename = "tmp/wt_Genus_over_time.tiff",
height = 9,
width = 12,
units = "in",
res = 600,
compression = "lzw+p")
print(p0)
graphics.off()
print(p0)
p1 <- ggplot(mu1,
aes(x = x,
y = Genus,
color = Trt_Genotype,
shape = Week)) +
geom_point(size = 3,
alpha = 0.5) +
geom_vline(xintercept = 1,
linetype = "dashed") +
scale_x_continuous("Relative Abundance (%)") +
theme(legend.position = "top")
tiff(filename = "tmp/wt_Genus_ra.tiff",
height = 9,
width = 9,
units = "in",
res = 600,
compression = "lzw+p")
print(p1)
graphics.off()
ggplotly(p1)
LS0tDQp0aXRsZTogIkRhdGEgVmlzdWFsaXphdGlvbiBvZiBXVCBhbmQgTnJmMiBLTyAoLS8tKSBCTDYgUEVJVEMgb3IgQ3JhbmJlcnJ5IFRyZWF0ZWQgTWljZSAxNlMgTWljcm9iaW9tZSBEYXRhIEFuYWx5c2lzLCBTZXB0ZW1iZXIgMjAxOSBCYXRjaCINCm91dHB1dDogDQogIGh0bWxfbm90ZWJvb2s6DQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQotLS0NCkRhdGU6IGByIGRhdGUoKWAgICAgIA0KU2NpZW50aXN0OiBbUmFuIFlpbl0obWFpbHRvOnJ5MTQ3QHNjYXJsZXRtYWlsLnJ1dGdlcnMuZWR1KSAgICAgIA0KU2VxdWVuY2luZyAoV2Frc21hbik6IFtEaWJ5ZW5kdSBLdW1hcl0obWFpbHRvOmRrQHdha3NtYW4ucnV0Z2Vycy5lZHUpICAgICAgDQpTdGF0aXN0aWNzOiBbRGF2aXQgU2FyZ3N5YW5dKG1haWx0bzpzYXJnZGF2aWRAZ21haWwuY29tKSAgICAgIA0KUHJpbmNpcGFsIEludmVzdGlnYXRvcjogW0FoLU5nIEtvbmddKG1haWx0bzprb25ndEBwaGFybWFjeS5ydXRnZXJzLmVkdSkgDQoNCmBgYHt9DQojIFRheG9ub21pYyBSYW5rczoNCiMgKipLKippbmcgKipQKipoaWxsaXAgKipDKiphbiBuKipPKip0ICoqRioqaW5kICoqRyoqcmVlbiAqKlMqKm9ja3MNCiMgKiBLaW5nZG9tICAgICAgICAgICAgICAgIA0KIyAqIFBoeWx1bSAgICAgICAgICAgICAgICAgICAgDQojICogQ2xhc3MgICAgICAgICAgICAgICAgICAgDQojICogT3JkZXIgICAgICAgICAgICAgICAgICAgDQojICogRmFtaWx5ICAgICANCiMgKiBHZW51cyAgICAgDQojICogU3BlY2llcyAgDQpgYGANCg0KYGBge3Igc2V0dXB9DQojIG9wdGlvbnMoc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFLA0KIyAgICAgICAgIHNjaXBlbiA9IDk5OSkNCg0KIyAjIEluY3JlYXNlIG1tZW1vcnkgc2l6ZSB0byA2NCBHYi0tLS0NCiMgaW52aXNpYmxlKHV0aWxzOjptZW1vcnkubGltaXQoNjU1MzYpKQ0KDQoNCiMgc3RyKGtuaXRyOjpvcHRzX2NodW5rJGdldCgpKQ0KIyAjIE5PVEU6IHRoZSBiZWxvdyBkb2VzIG5vdCB3b3JrIQ0KIyBrbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IEZBTFNFLCANCiMgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBGQUxTRSwNCiMgICAgICAgICAgICAgICAgICAgICAgIHdhcm5pbmcgPSBGQUxTRSwNCiMgICAgICAgICAgICAgICAgICAgICAgIGVycm9yID0gRkFMU0UpDQoNCiMgcmVxdWlyZShrbml0cikNCiMgcmVxdWlyZShrYWJsZUV4dHJhKQ0KcmVxdWlyZShwaHlsb3NlcSkNCiMgcmVxdWlyZShzaGlueSkNCg0KcmVxdWlyZShkYXRhLnRhYmxlKQ0KcmVxdWlyZShnZ3Bsb3QyKQ0KcmVxdWlyZShwbG90bHkpDQpyZXF1aXJlKERUKQ0KcmVxdWlyZShsbWVyVGVzdCkNCg0Kc291cmNlKCJzb3VyY2UvZnVuY3Rpb25zX21heTIwMTkuUiIpDQoNCiMgT24gV2luZG93cyBzZXQgbXVsdGl0aHJlYWQ9RkFMU0UtLS0tDQptdCA8LSBUUlVFDQpgYGANCg0KIyBJbnRyb2R1Y3Rpb24NCkM1N0JMLzYgd2lsZC10eXBlIChXVCkgYW5kIE5yZi0yIGRvdWJsZS1rbm9jay1vdXQgKEtPIC0vLSkgbWljZSB3ZXJlIGdpdmVuIDItd2VlayBtaWNyb2Jpb21lIHN0YWJpbGl6YXRpb24gcHJvY2VzcyB1c2luZyBBSU45M00gZGlldCBhbmQgOCBtb3JlIHdlZWtzIHRvIHRyZWF0IHdpdGggZWl0aGVyIEFJTjkzTSBvciBBSU45M00gNSUgUEVJVEMgZGlldC4gRmVjYWwgc2FtcGxlcyB3ZXJlIGNvbGxlY3RlZCB3ZWVrbHksIGltbWVkaWF0ZWx5IGZyb3plbiBpbiBsaXF1aWQgbml0cm9nZW4gYW5kIHN0b3JlZCBhdCAtODBeb15DLiBTZXJ1bSwgY2VjYWwsIGNvbG9uIGVwaXRoZWxpYWwgYW5kIHdob2xlIGNvbG9uIHRpc3N1ZXMgYXQgd2VlayAxMCB3ZXJlIGFsc28gY29sbGVjdGVkIGZvciBmdXJ0aGVyIGFuYWx5c2VzLiBCYXNlbGluZSwgd2VlayAxIGFuZCA0IGZlY2FsIHNhbXBsZXMgd2VyZSBzZWxlY3RlZCBmb3IgMTZzIHJSTkEgc2VxdWVuY2luZy4gIA0KICANClRoaXMgZG9jdW1lbnQgZXhhbWluZXMgcmVzdWx0cyBmcm9tIHRoZSBXVCBtaWNlIHNhbXBsZXMuICANCiAgDQpXZSB3aWxsIGF0dGFtcHQgdG8gYW5zd2VyIHRoZSBmb2xsb3dpbmcgcXVlc3Rpb25zOiAgDQoxLiBEaWQgbWljcm9iaW9tZSBjaGFuZ2Ugb3ZlciB0aW1lPyAgDQoyLiBXYXMgbWljcm9iaW9tZSBhZmZlY3RlZCBieSBkaWV0PyAgDQozLiBXYXMgdGhlcmUgYSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIEtPIGFuZCBXVD8gIA0KNC4gSWYgdGhlcmUgd2FzIGEgY2hhbmdlIGluIG1pY3JvYmlvbWUgY29tcG9zaXRpb24sIHdoYXQgZnVuY3Rpb25hbCBjaGFuZ2VzIGRpZCBpdCBjYXJyeT8gV2hhdCBhcmUgdGhlIGVzc2VudGlhbCBmdW5jdGlvbnMgb2YgdGhlIGJhY3RlcmlhIGFmZmVjdGVkIGJ5IHRoZSB0cmVhdG1lbnQgYW5kIGhvdyBjYW4gdGhpcyBiZSBzaG93biBpbiB2aXZvIChtZXRhYm9saXRlcywgaW5mbGFtbWF0aW9uIG1hcmtlcnMsIGV0Yy4pPw0KDQojIERhdGEgcHJlcHJvY2Vzc2luZw0KIyMgUmF3IERhdGEgDQpGYXN0USBmaWxlcyB3ZXJlIGRvd25sb2FkZWQgZnJvbSBbdGhpcyBSdXRnZXJzIEJveCBsb2NhdGlvbl0oaHR0cHM6Ly9ydXRnZXJzLmFwcC5ib3guY29tL2ZvbGRlci85MDE0MzQ2MjI5MSkuIEEgdG90YWwgb2YgMTQ0IGZpbGVzICgyIHBlciBzYW1wbGUsIHBhaXItZW5kZWQpIGFuZCBhIHBhaXIgb2YgdW5kZXRlcm1pbmVkIHJlYWRzIHdlcmUgZG93bmxvYWRlZC4gDQoNCiMjIFNjcmlwdA0KVGhpcyBzY3JpcHQgKCoqKm5yZjJ1YmlvbWVfZGFkYTJfc2VwMjAxOV92MS5SbWQqKiopIHdhcyBkZXZlbG9wZWQgdXNpbmcgW0RBREEyIFBpcGVsaW5lIFR1dG9yaWFsICgxLjEyKV0oaHR0cHM6Ly9iZW5qam5lYi5naXRodWIuaW8vZGFkYTIvdHV0b3JpYWwuaHRtbCkgd2l0aCB0aXBzIGFuZCB0cmlja3MgZnJvbSB0aGUgW1VuaXZlcnNpdHkgb2YgTWFyeWxhbmQgU2hvb2wgb2YgTWVkaWNpbmUgSW5zdGl0dXRlIGZvciBHZW5vbWUgU2NpZW5jZXMgKElHUyldKGh0dHA6Ly93d3cuaWdzLnVtYXJ5bGFuZC5lZHUvKSBbTWljcm9iaW9tZSBBbmFseXNpcyBXb3Jrc2hvcCAoQXByaWwgOC0xMSwgMjAxOSldKGh0dHA6Ly93d3cuaWdzLnVtYXJ5bGFuZC5lZHUvZWR1Y2F0aW9uL3drc2hwX21ldGFnZW5vbWUucGhwKS4gVGhlIG91dHB1dCBvZiB0aGUgREFEQTIgc2NyaXB0ICgqKipkYXRhX21heTIwMTkvcHNfc2VwMjAxOS5SRGF0YSoqKikgaXMgZXhwbG9yZWQgaW4gdGhpcyBkb2N1bWVudC4NCg0KIyBNZXRhIGRhdGE6IHNhbXBsZSBkZXNjcmlwdGlvbg0KYGBge3IgZGF0YX0NCiMgTG9hZCBkYXRhLS0tLQ0KIyBDb3VudHMNCmxvYWQoImRhdGFfc2VwMjAxOS9wc19zZXAyMDE5LlJEYXRhIikNCg0KIyBUYXhvbm9teQ0KbG9hZCgiZGF0YV9zZXAyMDE5L3RheGEuUkRhdGEiKQ0KdGF4YSA8LSBkYXRhLnRhYmxlKHNlcTE2cyA9IHJvd25hbWVzKHRheGEpLA0KICAgICAgICAgICAgICAgICAgIHRheGEpDQpgYGANCg0KKipOT1RFOiBjb3JyZWN0aW9uIHRvIHRoZSBtZXRhLWRhdGEhKiogKDExLzE1LzIwMTkpDQpgYGB7ciBjb3JyZWN0X21ldGFfZGF0YX0NCmNvcnJlY3Rfc2FtcGxlcyA8LSBmcmVhZCgiZGF0YV9zZXAyMDE5LzE2cyBtZXRhZGF0YSBTZXAtMjAxOS5jc3YiKQ0KcHNfc2VwMjAxOUBzYW1fZGF0YSREU1MgPC0gY29ycmVjdF9zYW1wbGVzJERTUw0KYGBgDQoNCiMgU2FtcGxlcw0KYGBge3Igc2FtcGxlc30NCnBzX3NlcDIwMTlAc2FtX2RhdGEkR2Vub3R5cGVfV2VlayA8LSBwYXN0ZShwc19zZXAyMDE5QHNhbV9kYXRhJGdlbm90eXBlLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzX3NlcDIwMTlAc2FtX2RhdGEkdGltZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXAgPSAiXyIpDQpwc19zZXAyMDE5QHNhbV9kYXRhJElEIDwtIGZhY3RvcihwYXN0ZTAocHNfc2VwMjAxOUBzYW1fZGF0YSRtaWNlX251bSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc19zZXAyMDE5QHNhbV9kYXRhJGNhZ2UpKQ0KDQpwc19zZXAyMDE5QHNhbV9kYXRhJFRSRUFUTUVOVCA8LSBwYXN0ZTAocHNfc2VwMjAxOUBzYW1fZGF0YSREU1MsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHNfc2VwMjAxOUBzYW1fZGF0YSRQRUlUQywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc19zZXAyMDE5QHNhbV9kYXRhJGNyYW5iZXJyeSkNCnBzX3NlcDIwMTlAc2FtX2RhdGEkVFJFQVRNRU5UIDwtIGZhY3Rvcihwc19zZXAyMDE5QHNhbV9kYXRhJFRSRUFUTUVOVCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCIwMDAiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjEwMCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMTEwIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIxMDEiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJOYWl2ZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRFNTIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEU1MrUEVJVEMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRTUytDcmFuYmVycnkiKSkNCg0Kc2FtcGxlcyA8LSBwc19zZXAyMDE5QHNhbV9kYXRhDQpkYXRhdGFibGUoc2FtcGxlcywNCiAgICAgICAgICBvcHRpb25zID0gbGlzdChwYWdlTGVuZ3RoID0gbnJvdyhzYW1wbGVzKSkpDQpgYGANCg0KIyBQcnVuZSBkYXRhDQpUaGUgT1RVcyB3ZXJlIG1hcHBlZCB0byBCYWN0ZXJpYSAoOTYuMDclKSwgRXVrYXJ5b3RhICgyLjk1JSkgYW5kIEFyY2hlYSAoMC4wMyUpIGtpbmdkb21zLCBhbmQgIDc1IE9UVXMgKDAuOTUlKSB1bmRlZmluZWQuIA0KDQpgYGB7ciBjaGVja19tYXBwaW5nX2tpbmdkb20sIHdhcm5pbmcgPSBGQUxTRSwgZWNobyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0V9DQp0MSA8LSBkYXRhLnRhYmxlKHRhYmxlKHRheF90YWJsZShwc19zZXAyMDE5KVssICJLaW5nZG9tIl0sDQogICAgICAgICAgICAgICAgICAgICAgIGV4Y2x1ZGUgPSBOVUxMKSkNCnQxJFYxW2lzLm5hKHQxJFYxKV0gPC0gIlVua25vd24iDQoNCnQxWywgcGN0IDo9IE4vc3VtKE4pXQ0Kc2V0b3JkZXIodDEsIC1OKQ0KDQpjb2xuYW1lcyh0MSkgPC0gYygiS2luZ2RvbSIsDQogICAgICAgICAgICAgICAgICAiTnVtYmVyIG9mIE9UVXMiLA0KICAgICAgICAgICAgICAgICAgIlBlcmNlbnQgb2YgT1RVcyIpDQpkYXRhdGFibGUodDEsDQogICAgICAgICAgcm93bmFtZXMgPSBGQUxTRSwNCiAgICAgICAgICBjYXB0aW9uID0gIk51bWJlciBvZiBPVFVzIGJ5IEtpbmdkb20iLA0KICAgICAgICAgIGNsYXNzID0gImNlbGwtYm9yZGVyIHN0cmlwZSIsDQogICAgICAgICAgb3B0aW9ucyA9IGxpc3Qoc2VhcmNoID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgICAgcGFnZUxlbmd0aCA9IG5yb3codDEpKSkgJT4lDQogIGZvcm1hdEN1cnJlbmN5KGNvbHVtbnMgPSAyLA0KICAgICAgICAgICAgICAgICBjdXJyZW5jeSA9ICIiLA0KICAgICAgICAgICAgICAgICBtYXJrID0gIiwiLA0KICAgICAgICAgICAgICAgICBkaWdpdHMgPSAwKSAlPiUNCiAgZm9ybWF0UGVyY2VudGFnZShjb2x1bW5zID0gMywNCiAgICAgICAgICAgICAgICAgICBkaWdpdHMgPSAyKQ0KYGBgDQoNClRoZSB0b3RhbCBvZiA3LDg2NyB1bmlxdWUgc2VxdWVuY2VzIHdlcmUgZm91bmQuIE91dCBvZiB0aG9zZSwgNyw1NTggd2VyZSBtYXBwZWQgdG8gYmFjdGVyaWFsIGdlbm9tZXMuIA0KDQpgYGB7ciBrZWVwX2JhY3RlcmlhfQ0KZGltKHBzX3NlcDIwMTlAb3R1X3RhYmxlQC5EYXRhKQ0KDQojIFJlbW92ZSBPVFUgbm90IG1hcHBlZCB0byBCYWN0ZXJpYQ0KcHMwIDwtIHN1YnNldF90YXhhKHBzX3NlcDIwMTksIA0KICAgICAgICAgICAgICAgICAgIEtpbmdkb20gPT0gIkJhY3RlcmlhIikNCmRpbShwczBAb3R1X3RhYmxlQC5EYXRhKQ0KYGBgDQogIA0KT3V0IG9mIHRoZSA3LDU1OCBPVFVzIDcsMjQ3IGJlbG9uZ2VkIHRvIDEyIFBoeWxhLiAzMTEgb2YgdGhlIE9UVXMgKG9yIDQuMTElIG9mIGJhY3RlcmlhbCBPVFVzKSBjb3VsZCBub3QgYmUgbWFwcGVkIHRvIGEgcGh5bHVtLg0KDQpgYGB7ciBwaHlsdW1fbWFwcGluZ30NCnQyIDwtIGRhdGEudGFibGUodGFibGUodGF4X3RhYmxlKHBzMClbLCAiUGh5bHVtIl0sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjbHVkZSA9IE5VTEwpKQ0KdDIkVjFbaXMubmEodDIkVjEpXSA8LSAiVW5rbm93biINCnNldG9yZGVyKHQyLCAtTikNCnQyWywgcGN0IDo9IE4vc3VtKE4pXQ0Kc2V0b3JkZXIodDIsIC1OKQ0KDQpjb2xuYW1lcyh0MikgPC0gYygiUGh5bHVtIiwNCiAgICAgICAgICAgICAgICAgICJOdW1iZXIgb2YgT1RVcyIsDQogICAgICAgICAgICAgICAgICAiUGVyY2VudCBvZiBPVFVzIikNCg0KZGF0YXRhYmxlKHQyLA0KICAgICAgICAgIHJvd25hbWVzID0gRkFMU0UsDQogICAgICAgICAgY2FwdGlvbiA9ICJOdW1iZXIgb2YgQmFjdGVyaWFsIE9UVXMgYnkgUGh5bHVtIiwNCiAgICAgICAgICBjbGFzcyA9ICJjZWxsLWJvcmRlciBzdHJpcGUiLA0KICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHNlYXJjaCA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2VMZW5ndGggPSBucm93KHQyKSkpICU+JQ0KICBmb3JtYXRDdXJyZW5jeShjb2x1bW5zID0gMiwNCiAgICAgICAgICAgICAgICAgY3VycmVuY3kgPSAiIiwNCiAgICAgICAgICAgICAgICAgbWFyayA9ICIsIiwNCiAgICAgICAgICAgICAgICAgZGlnaXRzID0gMCkgJT4lDQogIGZvcm1hdFBlcmNlbnRhZ2UoY29sdW1ucyA9IDMsDQogICAgICAgICAgICAgICAgICAgZGlnaXRzID0gMikNCmBgYA0KDQojIE9UVSB0YWJsZSAoZmlyc3QgMTAgcm93cykNCmBgYHtyIG90dV90YWJsZSwgd2FybmluZz1GQUxTRSxlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0V9DQpvdHUgPC0gZGF0YS50YWJsZShwczBAdGF4X3RhYmxlQC5EYXRhLA0KICAgICAgICAgICAgICAgICAgdChwczBAb3R1X3RhYmxlQC5EYXRhKSkNCmRhdGF0YWJsZShoZWFkKG90dSwgMTApLA0KICAgICAgICAgIHJvd25hbWVzID0gRkFMU0UsDQogICAgICAgICAgY2FwdGlvbiA9ICJUYXhvbm9taWMgIGNvdW50IHRhYmxlIiwNCiAgICAgICAgICBjbGFzcyA9ICJjZWxsLWJvcmRlciBzdHJpcGUiLA0KICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHNlYXJjaCA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2VMZW5ndGggPSAxMCkpICU+JQ0KICBmb3JtYXRDdXJyZW5jeShjb2x1bW5zID0gNzozNiwNCiAgICAgICAgICAgICAgICAgY3VycmVuY3kgPSAiIiwNCiAgICAgICAgICAgICAgICAgbWFyayA9ICIsIiwNCiAgICAgICAgICAgICAgICAgZGlnaXRzID0gMCkNCmBgYA0KDQojIFRvdGFsIGNvdW50cyBwZXIgc2FtcGxlIChpLmUuIHNlcXVlbmNpbmcgZGVwdGgpDQpgYGB7ciBzZXFfZGVwdGgsIGZpZy53aWR0aCA9IDEwLGZpZy5oZWlnaHQgPSA1fQ0KdDEgPC0gY29sU3VtcyhvdHVbLCA3Om5jb2wob3R1KV0pDQp0MSA8LSBkYXRhLnRhYmxlKFNBTVBMRV9OQU1FID0gbmFtZXModDEpLA0KICAgICAgICAgICAgICAgICBUb3RhbCA9IHQxKQ0KDQp0MiA8LSBkYXRhLnRhYmxlKFNBTVBMRV9OQU1FID0gcm93bmFtZXMoc2FtcGxlcyksDQogICAgICAgICAgICAgICAgIElEID0gc2FtcGxlcyRJRCwNCiAgICAgICAgICAgICAgICAgQ0FHRSA9IHNhbXBsZXMkY2FnZSwNCiAgICAgICAgICAgICAgICAgVFJFQVRNRU5UID0gc2FtcGxlcyRUUkVBVE1FTlQsDQogICAgICAgICAgICAgICAgIEdlbm90eXBlID0gc2FtcGxlcyRnZW5vdHlwZSwNCiAgICAgICAgICAgICAgICAgV0VFSyA9IHNhbXBsZXMkdGltZSkNCg0Kc21wbCA8LSBtZXJnZSh0MSwNCiAgICAgICAgICAgICAgdDIsDQogICAgICAgICAgICAgIGJ5ID0gIlNBTVBMRV9OQU1FIikNCg0KcDEgPC0gZ2dwbG90KHNtcGwsDQogICAgICAgICAgICAgYWVzKHggPSBTQU1QTEVfTkFNRSwNCiAgICAgICAgICAgICAgICAgeSA9IFRvdGFsLA0KICAgICAgICAgICAgICAgICBmaWxsID0gVFJFQVRNRU5ULA0KICAgICAgICAgICAgICAgICBjb2xvdXIgPSBXRUVLKSkgKw0KICBmYWNldF93cmFwKH4gR2Vub3R5cGUsDQogICAgICAgICAgICAgc2NhbGUgPSAiZnJlZV94IikgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKw0KICBzY2FsZV94X2Rpc2NyZXRlKCIiKSArDQogIHNjYWxlX3lfY29udGludW91cygiTnVtYmVyIG9mIFJlYWRzIikgKw0KICBzY2FsZV9maWxsX2Rpc2NyZXRlKCJUcmVhdG1lbnQiKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhqdXN0ID0gMSkpIA0KZ2dwbG90bHkocDEpDQpgYGANCg0KIyBSaWNobmVzcyAoQWxwaGEgZGl2ZXJzaXR5KQ0KU2hhbm5vbiBpbmRleCAoYWthIFNoYW5ub24gZW50aHJvcGh5KSBpcyBjYWxjdWxhdGVkIGFzOiAgDQpIJyA9IC1zdW0oMSB0byBSKXAoaSlsbihwKGkpKSANCldoZW4gdGhlcmUgaXMgZXhhY3RseSAxIHR5cGUgb2YgZGF0YSAoZS5nLiBhIHNpbmdsZSBzcGVjaWVzIGluIHRoZSBzYW1wbGUpLCBIJz0wLiBUaGUgb3Bwb3NpdGUgc2NlbmFyaW8gaXMgd2hlbiB0aGVyZSBhcmUgUj4xIHNwZWNpZXMgcHJlc2VudCBpbiB0aGUgc2FtcGxlIGluIHRoZSBleGFjdCBzYW1lIGFtb3VudHMgYW5kIEgnPWxuKFIpLiAgDQogIA0KU2hhbm5vbidzIGRpdmVyc2l0eSBpbmRleCB3YXMgY2FsY3VsYXRlZCBmb3IgZWFjaCBzYW1wbGUgYW5kIHBsb3RlZCBvdmVyIHRpbWUgdXNpbmcgdGhlIDcsNzY0IGZyb20gdGhlIDEzIFBoeWx1bSBhYm92ZS4NCiAgDQpgYGB7ciBzaGFubm9uX3ZzX2RlcHRoLCBmaWcuaGVpZ2h0ID0gNSwgZmlnLndpZHRoID0gNn0NCnNoYW5ub24ubmR4IDwtIGVzdGltYXRlX3JpY2huZXNzKHBzMCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lYXN1cmVzID0gIlNoYW5ub24iKQ0KDQpzaGFubm9uLm5keCA8LSBkYXRhLnRhYmxlKFNBTVBMRV9OQU1FID0gcm93bmFtZXMoc2hhbm5vbi5uZHgpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBzaGFubm9uLm5keCkNCg0Kc21wbCA8LSBtZXJnZShzbXBsLA0KICAgICAgICAgICAgICBzaGFubm9uLm5keCwNCiAgICAgICAgICAgICAgYnkgPSAiU0FNUExFX05BTUUiKQ0KDQpwMSA8LSBnZ3Bsb3Qoc21wbCwNCiAgICAgICAgICAgICBhZXMoeCA9IFRvdGFsLA0KICAgICAgICAgICAgICAgICB5ID0gU2hhbm5vbiwNCiAgICAgICAgICAgICAgICAgZmlsbCA9IEdlbm90eXBlLA0KICAgICAgICAgICAgICAgICBzaGFwZSA9IFdFRUspKSArDQogIGdlb21fcG9pbnQoc2l6ZSA9IDIpICsNCiAgc2NhbGVfc2hhcGVfbWFudWFsKGJyZWFrcyA9IHVuaXF1ZShzbXBsJFdFRUspLA0KICAgICAgICAgICAgICAgICAgICAgdmFsdWVzID0gMjE6MjMpDQoNCnRpZmYoZmlsZW5hbWUgPSAidG1wL3NoYW5ub25fdnNfZGVwdGgudGlmZiIsDQogICAgIGhlaWdodCA9IDUsDQogICAgIHdpZHRoID0gNiwNCiAgICAgdW5pdHMgPSAiaW4iLA0KICAgICByZXMgPSA2MDAsDQogICAgIGNvbXByZXNzaW9uID0gImx6dytwIikNCnByaW50KHAxKQ0KZ3JhcGhpY3Mub2ZmKCkNCg0KZ2dwbG90bHkocDEpDQpgYGANCg0KRXZlbiB0aG91Z2ggKioqZXN0aW1hdGVfcmljaG5lc3MqKiogZnVuY3Rpb24gZG9lcyBub3QgYWRqdXN0IGZvciB0aGUgc2VxdWVuY2luZyBkZXB0aCwgdGhlcmUgaXMgbm8gY29ycmVsYXRpb24gYmV0d2VlbiB0aGUgaW5kZXggYW5kIHRoZSBzYW1wbGUncyBzZXF1ZWNpbmcgZGVwdGguIFByb2NlZWQgd2l0aCB0aGUgY29tcGFyaXNvbi4NCg0KIyBTaGFubm9uIGlkZXggb3ZlciB0aW1lDQpgYGB7ciByaWNobmVzcywgZmlnLndpZHRoID0gNCwgZmlnLmhlaWdodCA9IDV9DQpwMSA8LSBwbG90X3JpY2huZXNzKHBzMCwNCiAgICAgICAgICAgICAgICAgICAgeCA9ICJ0aW1lIiwgDQogICAgICAgICAgICAgICAgICAgIG1lYXN1cmVzID0gIlNoYW5ub24iKSArDQogIGZhY2V0X3dyYXAofiBnZW5vdHlwZSkgKw0KICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gSUQpLA0KICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21fcG9pbnQoYWVzKGZpbGwgPSBUUkVBVE1FTlQpLA0KICAgICAgICAgICAgIHNoYXBlID0gMjEsDQogICAgICAgICAgICAgc2l6ZSA9IDMsDQogICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siKSArDQogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGp1c3QgPSAxLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2anVzdCA9IDEpKQ0KDQpnZ3Bsb3RseShwID0gcDEsDQogICAgICAgICB0b29sdGlwID0gYygiSUQiLA0KICAgICAgICAgICAgICAgICAgICAgInZhbHVlIikpDQoNCnAxIDwtIHAxICsgDQogIHNjYWxlX2ZpbGxfZGlzY3JldGUoIiIpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpDQoNCnRpZmYoZmlsZW5hbWUgPSAidG1wL3NoYW5ub24udGlmZiIsDQogICAgIGhlaWdodCA9IDQsDQogICAgIHdpZHRoID0gNSwNCiAgICAgdW5pdHMgPSAiaW4iLA0KICAgICByZXMgPSA2MDAsDQogICAgIGNvbXByZXNzaW9uID0gImx6dytwIikNCnByaW50KHAxKQ0KZ3JhcGhpY3Mub2ZmKCkNCmBgYA0KDQpUaGUgcGxvdCBhYm92ZSBzdWdnZXN0cyB0aGF0IHRoZSBsYXJnZXN0IGRpZmZlcmVuY2VzIGluIGFscGhhIGRpdmVyc2l0eSAoYXMgbWVhc3VyZWQgYnkgU2hhbm5vbidzIGluZGV4KSBhcmUgaW4gZ2Vub3R5cGUuDQogIA0KVGVzdCBpZiB0aGUgcmljaG5lc3MgY2hhbmdlZCBiZXR3ZWVuIHRoZSBiYXNlbGluZSBhbmQgV2VlayA4LiAgDQogIA0KYGBge3IgbG1fcmljaG5lc3N9DQpzbXBsJFRSRUFUTUVOVCA8LSBmYWN0b3Ioc21wbCRUUkVBVE1FTlQsDQogICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiRFNTIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOYWl2ZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRFNTK1BFSVRDIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEU1MrQ3JhbmJlcnJ5IikpDQoNCnRtcCA8LSBkcm9wbGV2ZWxzKHNtcGxbV0VFSyAhPSAid2VlazEiXSkNCg0KbTEgPC0gbG0oU2hhbm5vbiAgfiBXRUVLKihUUkVBVE1FTlQgKyBHZW5vdHlwZSksDQogICAgICAgICAjIG9mZnNldCA9IFRvdGFsLA0KICAgICAgICAgZGF0YSA9IHRtcCkNCnN1bW1hcnkobTEpDQpgYGANCiAgDQpgYGB7ciBsbWVyX3JpY2huZXNzfQ0KbTIgPC0gbG1lcihTaGFubm9uICB+IFdFRUsqKFRSRUFUTUVOVCArIEdlbm90eXBlKSArICgxIHwgSUQpLA0KICAgICAgICAgICAjIG9mZnNldCA9IFRvdGFsLA0KICAgICAgICAgICBkYXRhID0gdG1wKQ0Kc3VtbWFyeShtMikNCmBgYA0KDQojIENhbGN1bGF0ZSBjaGFuZ2UgaW4gU2hhbm5vbiBpbmRleCBmcm9tIGJhc2VsaW5lDQpgYGB7ciBkZWx0YV9zaGFubm9uLCBmaWcud2lkdGggPSA3LCBmaWcuaGVpZ2h0ID0gNX0NCmRkIDwtIHNtcGwNCmRkWywgZGVsdGEgOj0gU2hhbm5vbiAtIFNoYW5ub25bV0VFSyA9PSAiYmFzZWxpbmUiXSwNCiAgIGJ5ID0gSURdDQpkZCRkaWZmIDwtIHBhc3RlKGRkJFdFRUssDQogICAgICAgICAgICAgICAgICItYmFzZWxpbmUiLA0KICAgICAgICAgICAgICAgICBzZXAgPSAiIikNCg0KZGQgPC0gZGRbV0VFSyAhPSAiYmFzZWxpbmUiLF0NCg0KcDEgPC0gZ2dwbG90KGRkLA0KICAgICAgICAgICAgIGFlcyh4ID0gVFJFQVRNRU5ULA0KICAgICAgICAgICAgICAgICB5ID0gZGVsdGEsDQogICAgICAgICAgICAgICAgIGZpbGwgPSBHZW5vdHlwZSkpICsNCiAgZmFjZXRfd3JhcCh+IGRpZmYpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwNCiAgICAgICAgICAgICBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIGdlb21fcG9pbnQocG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjMpLA0KICAgICAgICAgICAgIHNoYXBlID0gMjEsDQogICAgICAgICAgICAgc2l6ZSA9IDMpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKCJTaGFubm9uIEluZGV4IFBlcmNlbnQgQ2hhbmdlIGZyb20gQmFzZWxpbmUiKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhqdXN0ID0gMSkpDQpwcmludChwMSkNCg0KZGQkVFJFQVRNRU5UIDwtIGZhY3RvcihkZCRUUkVBVE1FTlQsDQogICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJEU1MiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTmFpdmUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRFNTK1BFSVRDIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRTUytDcmFuYmVycnkiKSkNCmRkJEdlbm90eXBlIDwtIGZhY3RvcihkZCRHZW5vdHlwZSwNCiAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygid2lkZXR5cGUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJucmYyS08iKSkNCg0KbTEgPC0gbG0oZGVsdGEgfiBUUkVBVE1FTlQqR2Vub3R5cGUsDQogICAgICAgICBkYXRhID0gZGQpDQpzdW1tYXJ5KG0xKQ0KDQojIE5vIHNpZ25pZmljYW50IGludGVyYWN0aW9ucywgcHJvY2VlZCB3aXRoIDItd2F5IGFuYWx5c2lzDQptMiA8LSBsbShkZWx0YSB+IFRSRUFUTUVOVCArIEdlbm90eXBlLA0KICAgICAgICAgZGF0YSA9IGRkKQ0Kc3VtbWFyeShtMikNCmBgYA0KDQpBdCBXZWVrIDggdGhlcmUgd2FzIHNpZ25pZmljYW50bHkgc21hbGxlciBpbmNyZWFzZSBvZiBhbHBoYSBkaXZlcnNpdHkgZnJvbSBiYXNlbGluZSBpbiBOcmYyIEtPIGNvbXBhcmVkIHRvIFdULCBhbmQgaW4gRFNTK0NyYW5iZXJyeSBjb21wYXJlZCB0byBEU1Mgb25seS4NCg0KIyBMb2FkIGFtaW5vYWNpZHMNCmBgYHtyIGFtaW5vYWNpZHNfZGF0YX0NCmFhIDwtIGZyZWFkKCJkYXRhX3NlcDIwMTkvc2VwMjAxOV9hbWlub2FjaWRzLmNzdiIpDQoNCmFhIDwtIGFhWyFpcy5uYShJRCksIF0NCmFhJElEIDwtIHBhc3RlMChhYSRJRCwNCiAgICAgICAgICAgICAgICBhYSRDQUdFKQ0KDQpzbXBsMSA8LSB1bmlxdWUoc21wbFssIGMoIklEIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVFJFQVRNRU5UIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR2Vub3R5cGUiKV0pDQpzbXBsMSRJRCA8LSBhcy5jaGFyYWN0ZXIoc21wbDEkSUQpDQphYSA8LSBtZXJnZShzbXBsMSwNCiAgICAgICAgICAgIGFhLA0KICAgICAgICAgICAgYnkgPSAiSUQiKQ0KYWFbLCB0cnRfd2VlayA6PSBwYXN0ZShUUkVBVE1FTlQsDQogICAgICAgICAgICAgICAgICAgICAgIFdFRUssDQogICAgICAgICAgICAgICAgICAgICAgIHNlcCA9ICJfIildDQphYSR0cnRfd2VlayA8LSBmYWN0b3IoYWEkdHJ0X3dlZWssDQogICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiTmFpdmVfd2VlazIiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5haXZlX3dlZWs2IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEU1Nfd2VlazIiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRTU193ZWVrNiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRFNTK0NyYW5iZXJyeV93ZWVrMiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRFNTK0NyYW5iZXJyeV93ZWVrNiIgLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRTUytQRUlUQ193ZWVrMiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRFNTK1BFSVRDX3dlZWs2IikpDQpgYGANCg0KYGBge3IgYW1pbm9hY2lkc19wbG90cywgZmlnLmhlaWdodCA9IDQsIGZpZy53aWR0aCA9IDV9DQpmb3IgKGkgaW4gODoobmNvbChhYSkgLSAxKSkgew0KICB0bXAgPC0gYWFbLCBjKDEsIDMsIDcsIG5jb2woYWEpLCBpKSwgd2l0aCA9IEZBTFNFXQ0KICBjb2xuYW1lcyh0bXApWzVdIDwtICJZIg0KICBwMSA8LSBnZ3Bsb3QodG1wLA0KICAgICAgICAgICAgICAgYWVzKHggPSB0cnRfd2VlaywNCiAgICAgICAgICAgICAgICAgICB5ID0gWSwNCiAgICAgICAgICAgICAgICAgICBmaWxsID0gR2Vub3R5cGUsDQogICAgICAgICAgICAgICAgICAgZ3JvdXAgPSBJRCkpICsNCiAgICBnZW9tX2xpbmUocG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjMpKSArDQogICAgZ2VvbV9wb2ludChzaGFwZSA9IDIxLA0KICAgICAgICAgICAgICAgc2l6ZSA9IDMsDQogICAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuMykpICsNCiAgICBzY2FsZV94X2Rpc2NyZXRlKCIiKSArDQogICAgc2NhbGVfeV9jb250aW51b3VzKGNvbG5hbWVzKGFhKVtpXSkgKw0KICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGp1c3QgPSAxKSkNCiAgIyB0aWZmKGZpbGVuYW1lID0gcGFzdGUwKCJ0bXAvIiwNCiAgIyAgICAgICAgICAgICAgICAgICAgICAgIGNvbG5hbWVzKGFhKVtpXSwNCiAgIyAgICAgICAgICAgICAgICAgICAgICAgICIudGlmZiIpLA0KICAjICAgICAgaGVpZ2h0ID0gNCwNCiAgIyAgICAgIHdpZHRoID0gNSwNCiAgIyAgICAgIHVuaXRzID0gImluIiwNCiAgIyAgICAgIHJlcyA9IDYwMCwNCiAgIyAgICAgIGNvbXByZXNzaW9uID0gImx6dytwIikNCiAgIyBwcmludChwMSkNCiAgIyBncmFwaGljcy5vZmYoKQ0KICANCiAgcHJpbnQocDEpDQp9DQpgYGANCg0KIyBBbWlub2FjaWQgZGF0YSBQQ0ENCmBgYHtyIGFtaW5vYWNpZHNfcGNhfQ0KZHRfcGNhIDwtIGFhWywgQWxhbmluZTpnbHV0YW1pbmVdDQoNCm0xIDwtIHByY29tcChkdF9wY2EpDQpzdW1tYXJ5KG0xKQ0KDQoNCiMgU2VsZWN0IFBDLXMgdG8gcGxpb3QgKFBDMSAmIFBDMikNCmNob2ljZXMgPC0gMToyDQojIFNjb3JlcywgaS5lLiBwb2ludHMgKGRmLnUpDQpkdC5zY3IgPC0gZGF0YS50YWJsZShtMSR4WywgY2hvaWNlc10pDQojIEFkZCBncm91cGluZyB2YXJpYWJsZQ0KZHQuc2NyJGdycCA8LSBhYSR0cnRfd2Vlaw0KZHQuc2NyJFRSRUFUTUVOVCA8LSBhYSRUUkVBVE1FTlQNCmR0LnNjciRXRUVLIDwtIGFhJFdFRUsNCmR0LnNjcg0KDQojIExvYWRpbmdzLCBpLmUuIGFycm93cyAoZGYudikNCmR0LnJvdCA8LSBhcy5kYXRhLmZyYW1lKG0xJHJvdGF0aW9uWywgY2hvaWNlc10pDQpkdC5yb3QkZmVhdCA8LSByb3duYW1lcyhkdC5yb3QpDQpkdC5yb3QgPC0gZGF0YS50YWJsZShkdC5yb3QpDQpkdC5yb3QNCg0KZHQubG9hZCA8LSBtZWx0LmRhdGEudGFibGUoZHQucm90LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgaWQudmFycyA9ICJmZWF0IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lYXN1cmUudmFycyA9IDE6MiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhcmlhYmxlLm5hbWUgPSAicGMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUubmFtZSA9ICJsb2FkaW5nIikNCmR0LmxvYWQkZmVhdCA8LSBmYWN0b3IoZHQubG9hZCRmZWF0LA0KICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSB1bmlxdWUoZHQubG9hZCRmZWF0KSkNCiMgUGxvdCBsb2FkaW5ncw0KcDAgPC0gZ2dwbG90KGRhdGEgPSBkdC5sb2FkLA0KICAgICAgICAgICAgIGFlcyh4ID0gZmVhdCwNCiAgICAgICAgICAgICAgICAgeSA9IGxvYWRpbmcpKSArDQogIGZhY2V0X3dyYXAofiBwYywNCiAgICAgICAgICAgICBucm93ID0gMikgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKw0KICBnZ3RpdGxlKCJQQyBMb2FkaW5ncyIpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksDQogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhqdXN0ID0gMSkpDQp0aWZmKGZpbGVuYW1lID0gInRtcC9wYy4xLjJfbG9hZGluZ3MudGlmZiIsDQogICAgIGhlaWdodCA9IDUsDQogICAgIHdpZHRoID0gOCwNCiAgICAgdW5pdHMgPSAnaW4nLA0KICAgICByZXMgPSAzMDAsDQogICAgIGNvbXByZXNzaW9uID0gImx6dytwIikNCnByaW50KHAwKQ0KZ3JhcGhpY3Mub2ZmKCkNCg0KcHJpbnQocDApDQpgYGANCg0KYGBge3IgYW1pbm9hY2lkc19wY2FfYXhlc30NCiMgQXhpcyBsYWJlbHMNCnUuYXhpcy5sYWJzIDwtIHBhc3RlKGNvbG5hbWVzKGR0LnJvdClbMToyXSwgDQogICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKCcoJTAuMWYlJSBleHBsYWluZWQgdmFyLiknLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMTAwKm0xJHNkZXZbY2hvaWNlc11eMi9zdW0obTEkc2Rldl4yKSkpDQp1LmF4aXMubGFicw0KYGBgDQoNCmBgYHtyIGFtaW5vYWNpZHNfYmlwbG90LCBmaWcuaGVpZ2h0ID0gMTAsIGZpZy53aWR0aCA9IDEwfQ0KIyBCYXNlZCBvbiBGaWd1cmUgcDAsIGtlZXAgb25seSBhIGZldyB2YXJpYWJsZXMgd2l0aCBoaWdoIGxvYWRpbmdzIGluIFBDMSBhbmQgUEMyLS0tLQ0KIyB2YXIua2VlcC5uZHggPC0gd2hpY2goZHQucm90JGZlYXQgJWluJSBjKC4uLikpDQojIE9yIHNlbGVjdCBhbGwNCiMgdmFyLmtlZXAubmR4IDwtIDM6bmNvbChkdDEpDQojIFVzZSBkdC5yb3RbdmFyLmtlZXAubmR4LF0gYW5kIGR0LnJvdCRmZWF0W3Zhci5rZWVwLm5keF0NCnAxIDwtIGdncGxvdChkYXRhID0gZHQucm90LA0KICAgICAgICAgICAgIGFlcyh4ID0gUEMxLA0KICAgICAgICAgICAgICAgICB5ID0gUEMyKSkgKw0KICBjb29yZF9lcXVhbCgpICsNCiAgZ2VvbV9wb2ludChkYXRhID0gZHQuc2NyLA0KICAgICAgICAgICAgIGFlcyhmaWxsID0gZ3JwKSwNCiAgICAgICAgICAgICBzaGFwZSA9IDIxLA0KICAgICAgICAgICAgIHNpemUgPSAyLA0KICAgICAgICAgICAgIGFscGhhID0gMC41KSArDQogIGdlb21fc2VnbWVudChhZXMoeCA9IDAsDQogICAgICAgICAgICAgICAgICAgeSA9IDAsDQogICAgICAgICAgICAgICAgICAgeGVuZCA9IDEwKlBDMSwNCiAgICAgICAgICAgICAgICAgICB5ZW5kID0gMTAqUEMyKSwNCiAgICAgICAgICAgICAgIGFycm93ID0gYXJyb3cobGVuZ3RoID0gdW5pdCgxLzIsICdwaWNhcycpKSwNCiAgICAgICAgICAgICAgIHNpemUgPSAxLjIsIA0KICAgICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21fdGV4dChhZXMoeCA9IDExKlBDMSwNCiAgICAgICAgICAgICAgICB5ID0gMTEqUEMyLA0KICAgICAgICAgICAgICAgIGxhYmVsID0gZHQucm90JGZlYXQpLA0KICAgICAgICAgICAgIyBzaXplID0gNSwNCiAgICAgICAgICAgIGhqdXN0ID0gMC41KSArDQogIHNjYWxlX3hfY29udGludW91cyh1LmF4aXMubGFic1sxXSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModS5heGlzLmxhYnNbMl0pICsNCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lID0gIkdyb3VwIikgKw0KICBnZ3RpdGxlKCJCaXBsb3Qgb2YgQW1pbm9hY2lkcyIpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplID0gMjApKQ0KdGlmZihmaWxlbmFtZSA9ICJ0bXAvYW1pbm9hY2lkc19iaXBsb3QudGlmZiIsDQogICAgIGhlaWdodCA9IDEwLA0KICAgICB3aWR0aCA9IDEwLA0KICAgICB1bml0cyA9ICdpbicsDQogICAgIHJlcyA9IDMwMCwNCiAgICAgY29tcHJlc3Npb24gPSAibHp3K3AiKQ0KcHJpbnQocDEpDQpncmFwaGljcy5vZmYoKQ0KDQpnZ3Bsb3RseShwMSkNCmBgYA0KDQpgYGB7ciBhbWlub2FjaWRzX2JpcGxvdF9ieV93ZWVrLCBmaWcuaGVpZ2h0ID0gMTAsIGZpZy53aWR0aCA9IDEwfQ0KcDIgPC0gZ2dwbG90KGRhdGEgPSBkdC5yb3QsDQogICAgICAgICAgICAgYWVzKHggPSBQQzEsDQogICAgICAgICAgICAgICAgIHkgPSBQQzIpKSArDQogIGNvb3JkX2VxdWFsKCkgKw0KICBnZW9tX3BvaW50KGRhdGEgPSBkdC5zY3IsDQogICAgICAgICAgICAgYWVzKGZpbGwgPSBXRUVLKSwNCiAgICAgICAgICAgICBzaGFwZSA9IDIxLA0KICAgICAgICAgICAgIHNpemUgPSAyLA0KICAgICAgICAgICAgIGFscGhhID0gMC41KSArDQogIGdlb21fc2VnbWVudChhZXMoeCA9IDAsDQogICAgICAgICAgICAgICAgICAgeSA9IDAsDQogICAgICAgICAgICAgICAgICAgeGVuZCA9IDEwKlBDMSwNCiAgICAgICAgICAgICAgICAgICB5ZW5kID0gMTAqUEMyKSwNCiAgICAgICAgICAgICAgIGFycm93ID0gYXJyb3cobGVuZ3RoID0gdW5pdCgxLzIsICdwaWNhcycpKSwNCiAgICAgICAgICAgICAgIHNpemUgPSAxLjIsIA0KICAgICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21fdGV4dChhZXMoeCA9IDExKlBDMSwNCiAgICAgICAgICAgICAgICB5ID0gMTEqUEMyLA0KICAgICAgICAgICAgICAgIGxhYmVsID0gZHQucm90JGZlYXQpLA0KICAgICAgICAgICAgIyBzaXplID0gNSwNCiAgICAgICAgICAgIGhqdXN0ID0gMC41KSArDQogIHNjYWxlX3hfY29udGludW91cyh1LmF4aXMubGFic1sxXSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModS5heGlzLmxhYnNbMl0pICsNCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lID0gIldlZWsiKSArDQogIGdndGl0bGUoIkJpcGxvdCBvZiBBbWlub2FjaWRzIikgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemUgPSAyMCkpDQp0aWZmKGZpbGVuYW1lID0gInRtcC9hbWlub2FjaWRzX2J5X3dlZWtfYmlwbG90LnRpZmYiLA0KICAgICBoZWlnaHQgPSAxMCwNCiAgICAgd2lkdGggPSAxMCwNCiAgICAgdW5pdHMgPSAnaW4nLA0KICAgICByZXMgPSAzMDAsDQogICAgIGNvbXByZXNzaW9uID0gImx6dytwIikNCnByaW50KHAyKQ0KZ3JhcGhpY3Mub2ZmKCkNCg0KZ2dwbG90bHkocDIpDQpgYGANCg0KYGBge3IgYW1pbm9hY2lkc19iaXBsb3RfYnlfdHJ0LCBmaWcuaGVpZ2h0ID0gMTAsIGZpZy53aWR0aCA9IDEwfQ0KcDIgPC0gZ2dwbG90KGRhdGEgPSBkdC5yb3QsDQogICAgICAgICAgICAgYWVzKHggPSBQQzEsDQogICAgICAgICAgICAgICAgIHkgPSBQQzIpKSArDQogIGNvb3JkX2VxdWFsKCkgKw0KICBnZW9tX3BvaW50KGRhdGEgPSBkdC5zY3IsDQogICAgICAgICAgICAgYWVzKGZpbGwgPSBUUkVBVE1FTlQpLA0KICAgICAgICAgICAgIHNoYXBlID0gMjEsDQogICAgICAgICAgICAgc2l6ZSA9IDIsDQogICAgICAgICAgICAgYWxwaGEgPSAwLjUpICsNCiAgZ2VvbV9zZWdtZW50KGFlcyh4ID0gMCwNCiAgICAgICAgICAgICAgICAgICB5ID0gMCwNCiAgICAgICAgICAgICAgICAgICB4ZW5kID0gMTAqUEMxLA0KICAgICAgICAgICAgICAgICAgIHllbmQgPSAxMCpQQzIpLA0KICAgICAgICAgICAgICAgYXJyb3cgPSBhcnJvdyhsZW5ndGggPSB1bml0KDEvMiwgJ3BpY2FzJykpLA0KICAgICAgICAgICAgICAgc2l6ZSA9IDEuMiwgDQogICAgICAgICAgICAgICBjb2xvciA9ICJibGFjayIpICsNCiAgZ2VvbV90ZXh0KGFlcyh4ID0gMTEqUEMxLA0KICAgICAgICAgICAgICAgIHkgPSAxMSpQQzIsDQogICAgICAgICAgICAgICAgbGFiZWwgPSBkdC5yb3QkZmVhdCksDQogICAgICAgICAgICAjIHNpemUgPSA1LA0KICAgICAgICAgICAgaGp1c3QgPSAwLjUpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKHUuYXhpcy5sYWJzWzFdKSArDQogIHNjYWxlX3lfY29udGludW91cyh1LmF4aXMubGFic1syXSkgKw0KICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWUgPSAiVHJlYXRtZW50IikgKw0KICBnZ3RpdGxlKCJCaXBsb3Qgb2YgQW1pbm9hY2lkcyIpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplID0gMjApKQ0KdGlmZihmaWxlbmFtZSA9ICJ0bXAvYW1pbm9hY2lkc19ieV90cnRfYmlwbG90LnRpZmYiLA0KICAgICBoZWlnaHQgPSAxMCwNCiAgICAgd2lkdGggPSAxMCwNCiAgICAgdW5pdHMgPSAnaW4nLA0KICAgICByZXMgPSAzMDAsDQogICAgIGNvbXByZXNzaW9uID0gImx6dytwIikNCnByaW50KHAyKQ0KZ3JhcGhpY3Mub2ZmKCkNCg0KZ2dwbG90bHkocDIpDQpgYGANCiMgUmVtb3ZlIHVubWFwcGVkIE9UVXMNClRoZSAzMTEgdW5tYXBwZWQgT1RVcyB3ZXJlIHJlbW92ZWQgZnJvbSBmdXJ0aGVyIGFuYWx5c2lzICh3aXRoIDcsMjQ3IE9UVXMgbGVmdCkuDQpgYGB7ciByZW1vdmVfdW5tYXBwZWRfb3R1X3BoeWx1bX0NCnBzMSA8LSBzdWJzZXRfdGF4YShwczAsIA0KICAgICAgICAgICAgICAgICAgICFpcy5uYShQaHlsdW0pKQ0KZGltKHBzMUBvdHVfdGFibGVALkRhdGEpDQpgYGANCg0KIyBDb3VudHMgYXQgUGh5bHVtIGxldmVsDQpgYGB7ciBjb3VudHNfcCwgd2FybmluZz1GQUxTRSxlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0V9DQpjb3VudHNfcCA8LSBjb3VudHNfYnlfdGF4X3JhbmsoZHQxID0gb3R1LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFnZ3JfYnkgPSAiUGh5bHVtIikNCnNldG9yZGVyKGNvdW50c19wLCAtYDE5MDkxOS0wMWApDQpkYXRhdGFibGUoY291bnRzX3AsDQogICAgICAgICAgcm93bmFtZXMgPSBGQUxTRSwNCiAgICAgICAgICBjYXB0aW9uID0gIlRheG9ub21pYyAgY291bnQgdGFibGUiLA0KICAgICAgICAgIGNsYXNzID0gImNlbGwtYm9yZGVyIHN0cmlwZSIsDQogICAgICAgICAgb3B0aW9ucyA9IGxpc3Qoc2VhcmNoID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgICAgcGFnZUxlbmd0aCA9IG5yb3coY291bnRzX3ApKSkgJT4lDQogIGZvcm1hdEN1cnJlbmN5KGNvbHVtbnMgPSAyOm5jb2woY291bnRzX3ApLA0KICAgICAgICAgICAgICAgICBjdXJyZW5jeSA9ICIiLA0KICAgICAgICAgICAgICAgICBtYXJrID0gIiwiLA0KICAgICAgICAgICAgICAgICBkaWdpdHMgPSAwKQ0KYGBgDQoNCiMgUmVsYXRpdmUgYWJ1bmRhbmNlICglKSBhdCBQaHlsdW0gbGV2ZWwNCmBgYHtyIHJhX3AsIHdhcm5pbmc9RkFMU0UsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFfQ0KcmFfcCA8LSByYV9ieV90YXhfcmFuayhjb3VudHMgPSBjb3VudHNfcCwNCiAgICAgICAgICAgICAgICAgICAgICAgcGN0ID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgIGRpZ2l0ID0gNCkNCg0KZGF0YXRhYmxlKHJhX3AsDQogICAgICAgICAgcm93bmFtZXMgPSBGQUxTRSwNCiAgICAgICAgICBjYXB0aW9uID0gIlRheG9ub21pYyAgY291bnQgdGFibGUiLA0KICAgICAgICAgIGNsYXNzID0gImNlbGwtYm9yZGVyIHN0cmlwZSIsDQogICAgICAgICAgb3B0aW9ucyA9IGxpc3Qoc2VhcmNoID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgICAgcGFnZUxlbmd0aCA9IG5yb3cocmFfcCkpKSAlPiUNCiAgZm9ybWF0UGVyY2VudGFnZShjb2x1bW5zID0gMjpuY29sKGNvdW50c19wKSwNCiAgICAgICAgICAgICAgICAgICBkaWdpdHMgPSAyKQ0KYGBgDQoNClJlbW92ZSBwaHlsYSB3aXRoIHJlbGF0aXZlIGFidW5kYW5jZSBvZiA+PSAxJSBpbiBsZXNzIHRoYW4gMTAlIG9mIHNhbXBsZXMuDQoNCmBgYHtyIHByZXZfcH0NCnQxIDwtIGRhdGEudGFibGUoUGh5bHVtID0gcmFfcCRQaHlsdW0sDQogICAgICAgICAgICAgICAgIGBOdW1iZXIgb2YgU2FtcGxlc2AgPSByb3dTdW1zKHJhX3BbLCAyOm5jb2wocmFfcCldID49IDAuMDEpKQ0KdDEkYFBlcmNlbnQgU2FtcGxlc2AgPC0gIHQxJGBOdW1iZXIgb2YgU2FtcGxlc2AvNzINCg0Kc2V0b3JkZXIodDEsIC1gTnVtYmVyIG9mIFNhbXBsZXNgKQ0KZGF0YXRhYmxlKHQxLA0KICAgICAgICAgIHJvd25hbWVzID0gRkFMU0UsDQogICAgICAgICAgY2FwdGlvbiA9ICJUYXhvbm9taWMgIGNvdW50IHRhYmxlIiwNCiAgICAgICAgICBjbGFzcyA9ICJjZWxsLWJvcmRlciBzdHJpcGUiLA0KICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHNlYXJjaCA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2VMZW5ndGggPSBucm93KHQxKSkpICU+JQ0KICBmb3JtYXRQZXJjZW50YWdlKGNvbHVtbnMgPSAzLA0KICAgICAgICAgICAgICAgICAgIGRpZ2l0cyA9IDEpDQpgYGANCg0KV2Ugd2lsbCByZW1vdmUgQ2hsYW15ZGlhZSBmcm9tIHRoaXMgYW5hbHlzaXMuDQoNCmBgYHtyIGtlZXBfNl9waHlsYSwgd2FybmluZz1GQUxTRSxlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0V9DQprZWVwX3AgPC0gdDEkUGh5bHVtW3QxJGBQZXJjZW50IFNhbXBsZXNgID49IDAuMV0NCiMgIyBLZWVwIGFsbA0KIyBrZWVwX3AgPC0gdDEkUGh5bHVtDQoNCnBhc3RlMChrZWVwX3AsIGNvbGxhcHNlID0gIiwgIikNCg0KcHMxIDwtIHN1YnNldF90YXhhKHBzMCwgDQogICAgICAgICAgICAgICAgICAgUGh5bHVtICVpbiUga2VlcF9wICkNCm90dTEgPC0gZGF0YS50YWJsZShwczFAdGF4X3RhYmxlQC5EYXRhLA0KICAgICAgICAgICAgICAgICAgIHQocHMxQG90dV90YWJsZUAuRGF0YSkpDQoNCmRhdGF0YWJsZShoZWFkKG90dTEsIDEwKSwNCiAgICAgICAgICByb3duYW1lcyA9IEZBTFNFLA0KICAgICAgICAgIGNhcHRpb24gPSAiVGF4b25vbWljICBjb3VudCB0YWJsZSIsDQogICAgICAgICAgY2xhc3MgPSAiY2VsbC1ib3JkZXIgc3RyaXBlIiwNCiAgICAgICAgICBvcHRpb25zID0gbGlzdChzZWFyY2ggPSBGQUxTRSwNCiAgICAgICAgICAgICAgICAgICAgICAgICBwYWdlTGVuZ3RoID0gMTApKSAlPiUNCiAgZm9ybWF0Q3VycmVuY3koY29sdW1ucyA9IDc6bmNvbChvdHUxKSwNCiAgICAgICAgICAgICAgICAgY3VycmVuY3kgPSAiIiwNCiAgICAgICAgICAgICAgICAgbWFyayA9ICIsIiwNCiAgICAgICAgICAgICAgICAgZGlnaXRzID0gMCkNCmBgYA0KDQpYWCBPVFVzLCBkb3duIGZyb20gWVkgT1RVcyBpbiB0aGUgcHJldmlvdXMgdGFibGUuDQoNCg0KIyBSZWxhdGl2ZSBBYnVuZGFuY2UgaW4gU2FtcGxlcyBhdCBEaWZmZXJlbnQgVGF4b25vbWljIFJhbmtzDQojIyAxLiBDbGFzcw0KYGBge3IgY291bnRzX2MsIHdhcm5pbmc9RkFMU0UsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFLGZpZy53aWR0aD0xNSxmaWcuaGVpZ2h0PTE1fQ0KY291bnRzX2MgPC0gY291bnRzX2J5X3RheF9yYW5rKGR0MSA9IG90dTEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWdncl9ieSA9ICJDbGFzcyIpDQpyYV9jIDwtIHJhX2J5X3RheF9yYW5rKGNvdW50c19jKQ0KDQp0YXgucmFua3MgPC0gdW5pcXVlKG90dTFbLCBjKCJQaHlsdW0iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ2xhc3MiKV0pDQoNCnJhX2MgPC0gbWVyZ2UodGF4LnJhbmtzLA0KICAgICAgICAgICAgICByYV9jLA0KICAgICAgICAgICAgICBieSA9ICJDbGFzcyIpDQoNCnRvdGFsIDwtIHJvd1N1bXMocmFfY1ssIDM6bmNvbChyYV9jKV0pDQoNCnJhX2MkQ2xhc3MgPC0gZmFjdG9yKHJhX2MkQ2xhc3MsDQogICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSByYV9jJENsYXNzW29yZGVyKHRvdGFsKV0pDQoNCnJhX2MkUGh5bHVtIDwtIGZhY3RvcihyYV9jJFBoeWx1bSwNCiAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSB1bmlxdWUocmFfYyRQaHlsdW1bb3JkZXIodG90YWwpXSkpDQp0bXAgPC0gbWVsdC5kYXRhLnRhYmxlKGRhdGEgPSByYV9jLA0KICAgICAgICAgICAgICAgICAgICAgICBpZC52YXJzID0gMToyLA0KICAgICAgICAgICAgICAgICAgICAgICBtZWFzdXJlLnZhcnMgPSAzOm5jb2woY291bnRzX2MpLA0KICAgICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZS5uYW1lID0gIlNBTVBMRV9OQU1FIiwNCiAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUubmFtZSA9ICJSQSIpDQoNCnRtcCA8LSBtZXJnZShkYXRhLnRhYmxlKFNBTVBMRV9OQU1FID0gc21wbCRTQU1QTEVfTkFNRSwNCiAgICAgICAgICAgICAgICAgICAgICAgIFdFRUsgPSBzbXBsJFdFRUssDQogICAgICAgICAgICAgICAgICAgICAgICBUUkVBVE1FTlQgPSBzbXBsJFRSRUFUTUVOVCwNCiAgICAgICAgICAgICAgICAgICAgICAgIEdlbm90eXBlID0gc21wbCRHZW5vdHlwZSksDQogICAgICAgICAgICAgdG1wLA0KICAgICAgICAgICAgIGJ5ID0gIlNBTVBMRV9OQU1FIikNCg0KIyBQbG90IHNhbXBsZXMNCnAxIDwtIGdncGxvdCh0bXAsDQogICAgICAgICAgICAgYWVzKHggPSBTQU1QTEVfTkFNRSwNCiAgICAgICAgICAgICAgICAgeSA9IFJBLA0KICAgICAgICAgICAgICAgICBmaWxsID0gQ2xhc3MsDQogICAgICAgICAgICAgICAgIGNvbG9yID0gUGh5bHVtKSkgKw0KICBmYWNldF93cmFwKH4gV0VFSyArIFRSRUFUTUVOVCArIEdlbm90eXBlLA0KICAgICAgICAgICAgIHNjYWxlcyA9ICJmcmVlX3giLA0KICAgICAgICAgICAgIG5yb3cgPSAzKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArDQogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwgMCkpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoanVzdCA9IDEpKQ0KZ2dwbG90bHkocDEpDQpgYGANCg0KYGBge3IgbWVhbnNfYywgZWNobyA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRX0NCmxyYSA8LSByYV9tZWx0KHJhID0gcmFfYywNCiAgICAgICAgICAgICAgIHNhbXBsZXMgPSBzbXBsLA0KICAgICAgICAgICAgICAgc2FtcGxlX25hbWUgPSAiU0FNUExFX05BTUUiKQ0KDQptdSA8LSBkYXRhLnRhYmxlKGFnZ3JlZ2F0ZShscmEkUkEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICBieSA9IGxpc3QoV2VlayA9IGxyYSRXRUVLLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRyZWF0bWVudCA9IGxyYSRUUkVBVE1FTlQsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2Vub3R5cGUgPSBscmEkR2Vub3R5cGUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3MgPSBscmEkQ2xhc3MpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgRlVOID0gIm1lYW4iKSkNCm11WywgdG90YWwgOj0gc3VtKHgpLA0KICAgYnkgPSAiQ2xhc3MiXQ0KdWwgPC0gdW5pcXVlKG11WywgYygiQ2xhc3MiLCANCiAgICAgICAgICAgICAgICAgICAgInRvdGFsIildKQ0KdWwgPC0gdWxbb3JkZXIodG90YWwpLF0NCm11JENsYXNzIDwtIGZhY3RvcihtdSRDbGFzcywNCiAgICAgICAgICAgICAgICAgICBsZXZlbCA9IHVsJENsYXNzKQ0KbXUkdG90YWwgPC0gTlVMTA0KDQpkYXRhdGFibGUobXUsDQogICAgICAgICAgcm93bmFtZXMgPSBGQUxTRSwNCiAgICAgICAgICBjYXB0aW9uID0gIlRheG9ub21pYyAgY291bnQgdGFibGUiLA0KICAgICAgICAgIGNsYXNzID0gImNlbGwtYm9yZGVyIHN0cmlwZSIsDQogICAgICAgICAgb3B0aW9ucyA9IGxpc3Qoc2VhcmNoID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgICAgcGFnZUxlbmd0aCA9IDEwLA0KICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyID0gbGlzdChsaXN0KDMsICdkZXNjJykpKSkgJT4lDQogIGZvcm1hdEN1cnJlbmN5KGNvbHVtbnMgPSA1LA0KICAgICAgICAgICAgICAgICBjdXJyZW5jeSA9ICIiLA0KICAgICAgICAgICAgICAgICBtYXJrID0gIiwiLA0KICAgICAgICAgICAgICAgICBkaWdpdHMgPSAyKQ0KYGBgDQoNCg0KYGBge3IgbWVhbnNfY19wMCwgZmlnLndpZHRoID0gOSwgZmlnLmhlaWdodCA9IDd9DQptdSRUcnRfR2Vub3R5cGUgPC0gZmFjdG9yKHBhc3RlKG11JFRyZWF0bWVudCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgbXUkR2Vub3R5cGUsDQogICAgICAgICAgICAgICAgICAgICAgICAgIHNlcCA9ICJfIikpDQoNCnAwIDwtIGdncGxvdChtdSwNCiAgICAgICAgICAgICBhZXMoeCA9IFdlZWssDQogICAgICAgICAgICAgICAgIHkgPSB4LA0KICAgICAgICAgICAgICAgICBncm91cCA9IFRydF9HZW5vdHlwZSkpICsNCiAgZmFjZXRfd3JhcCh+IENsYXNzLA0KICAgICAgICAgICAgIHNjYWxlID0gImZyZWVfeSIpICsNCiAgZ2VvbV9saW5lKHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC4zKSkgKw0KICBnZW9tX3BvaW50KGFlcyhmaWxsID0gVHJ0X0dlbm90eXBlKSwNCiAgICAgICAgICAgICBzaGFwZSA9IDIxLA0KICAgICAgICAgICAgIHNpemUgPSAyLA0KICAgICAgICAgICAgIGFscGhhID0gMC41LA0KICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC4zKSkgKw0KICBzY2FsZV94X2Rpc2NyZXRlKCIiKSArDQogIHNjYWxlX3lfY29udGludW91cygiUmVsYXRpdmUgQWJ1bmRhbmNlICglKSIpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIsDQogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhqdXN0ID0gMSkpDQoNCnRpZmYoZmlsZW5hbWUgPSAidG1wL3d0X2NsYXNzX292ZXJfdGltZS50aWZmIiwNCiAgICAgaGVpZ2h0ID0gNSwNCiAgICAgd2lkdGggPSA3LA0KICAgICB1bml0cyA9ICJpbiIsDQogICAgIHJlcyA9IDYwMCwNCiAgICAgY29tcHJlc3Npb24gPSAibHp3K3AiKQ0KcHJpbnQocDApDQpncmFwaGljcy5vZmYoKQ0KDQpwcmludChwMCkNCmBgYA0KDQoNCmBgYHtyIG1lYW5zX2NfcDEsIGZpZy5oZWlnaHQgPSA1LCBmaWcud2lkdGggPSA5fQ0KcDEgPC0gZ2dwbG90KG11LA0KICAgICAgICAgICAgIGFlcyh4ID0geCwNCiAgICAgICAgICAgICAgICAgeSA9IENsYXNzLA0KICAgICAgICAgICAgICAgICBjb2xvciA9IFRydF9HZW5vdHlwZSwNCiAgICAgICAgICAgICAgICAgc2hhcGUgPSBXZWVrKSkgKw0KICBnZW9tX3BvaW50KHNpemUgPSAzLA0KICAgICAgICAgICAgIGFscGhhID0gMC41KSArDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDEsDQogICAgICAgICAgICAgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoIlJlbGF0aXZlIEFidW5kYW5jZSAoJSkiKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKQ0KDQp0aWZmKGZpbGVuYW1lID0gInRtcC93dF9jbGFzc19yYS50aWZmIiwNCiAgICAgaGVpZ2h0ID0gNCwNCiAgICAgd2lkdGggPSA3LA0KICAgICB1bml0cyA9ICJpbiIsDQogICAgIHJlcyA9IDYwMCwNCiAgICAgY29tcHJlc3Npb24gPSAibHp3K3AiKQ0KcHJpbnQocDEpDQpncmFwaGljcy5vZmYoKQ0KDQpnZ3Bsb3RseShwMSkNCmBgYA0KDQojIyAyLiBPcmRlcg0KYGBge3IgY291bnRzX28sIHdhcm5pbmc9RkFMU0UsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFLGZpZy53aWR0aD0xNSxmaWcuaGVpZ2h0PTE1fQ0KY291bnRzX28gPC0gY291bnRzX2J5X3RheF9yYW5rKGR0MSA9IG90dTEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWdncl9ieSA9ICJPcmRlciIpDQpyYV9vIDwtIHJhX2J5X3RheF9yYW5rKGNvdW50c19vKQ0KDQp0YXgucmFua3MgPC0gdW5pcXVlKG90dTFbLCBjKCJQaHlsdW0iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiT3JkZXIiKV0pDQoNCnJhX28gPC0gbWVyZ2UodGF4LnJhbmtzLA0KICAgICAgICAgICAgICByYV9vLA0KICAgICAgICAgICAgICBieSA9ICJPcmRlciIpDQoNCnRvdGFsIDwtIHJvd1N1bXMocmFfb1ssIDM6bmNvbChyYV9vKV0pDQoNCnJhX28kT3JkZXIgPC0gZmFjdG9yKHJhX28kT3JkZXIsDQogICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSByYV9vJE9yZGVyW29yZGVyKHRvdGFsKV0pDQoNCnJhX28kUGh5bHVtIDwtIGZhY3RvcihyYV9vJFBoeWx1bSwNCiAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSB1bmlxdWUocmFfbyRQaHlsdW1bb3JkZXIodG90YWwpXSkpDQp0bXAgPC0gbWVsdC5kYXRhLnRhYmxlKGRhdGEgPSByYV9vLA0KICAgICAgICAgICAgICAgICAgICAgICBpZC52YXJzID0gMToyLA0KICAgICAgICAgICAgICAgICAgICAgICBtZWFzdXJlLnZhcnMgPSAzOm5jb2woY291bnRzX28pLA0KICAgICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZS5uYW1lID0gIlNBTVBMRV9OQU1FIiwNCiAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUubmFtZSA9ICJSQSIpDQoNCnRtcCA8LSBtZXJnZShkYXRhLnRhYmxlKFNBTVBMRV9OQU1FID0gc21wbCRTQU1QTEVfTkFNRSwNCiAgICAgICAgICAgICAgICAgICAgICAgIFdFRUsgPSBzbXBsJFdFRUssDQogICAgICAgICAgICAgICAgICAgICAgICBUUkVBVE1FTlQgPSBzbXBsJFRSRUFUTUVOVCwNCiAgICAgICAgICAgICAgICAgICAgICAgIEdlbm90eXBlID0gc21wbCRHZW5vdHlwZSksDQogICAgICAgICAgICAgdG1wLA0KICAgICAgICAgICAgIGJ5ID0gIlNBTVBMRV9OQU1FIikNCg0KIyBQbG90IHNhbXBsZXMNCnAxIDwtIGdncGxvdCh0bXAsDQogICAgICAgICAgICAgYWVzKHggPSBTQU1QTEVfTkFNRSwNCiAgICAgICAgICAgICAgICAgeSA9IFJBLA0KICAgICAgICAgICAgICAgICBmaWxsID0gT3JkZXIsDQogICAgICAgICAgICAgICAgIGNvbG9yID0gUGh5bHVtKSkgKw0KICBmYWNldF93cmFwKH4gV0VFSyArIFRSRUFUTUVOVCArIEdlbm90eXBlLA0KICAgICAgICAgICAgIHNjYWxlcyA9ICJmcmVlX3giLA0KICAgICAgICAgICAgIG5yb3cgPSAzKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArDQogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwgMCkpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoanVzdCA9IDEpKQ0KZ2dwbG90bHkocDEpDQpgYGANCg0KYGBge3IgbWVhbnNfbywgZWNobyA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRX0NCmxyYSA8LSByYV9tZWx0KHJhID0gcmFfbywNCiAgICAgICAgICAgICAgIHNhbXBsZXMgPSBzbXBsLA0KICAgICAgICAgICAgICAgc2FtcGxlX25hbWUgPSAiU0FNUExFX05BTUUiKQ0KDQptdSA8LSBkYXRhLnRhYmxlKGFnZ3JlZ2F0ZShscmEkUkEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICBieSA9IGxpc3QoV2VlayA9IGxyYSRXRUVLLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRyZWF0bWVudCA9IGxyYSRUUkVBVE1FTlQsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2Vub3R5cGUgPSBscmEkR2Vub3R5cGUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT3JkZXIgPSBscmEkT3JkZXIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgRlVOID0gIm1lYW4iKSkNCm11WywgdG90YWwgOj0gc3VtKHgpLA0KICAgYnkgPSAiT3JkZXIiXQ0KdWwgPC0gdW5pcXVlKG11WywgYygiT3JkZXIiLCANCiAgICAgICAgICAgICAgICAgICAgInRvdGFsIildKQ0KdWwgPC0gdWxbb3JkZXIodG90YWwpLF0NCm11JE9yZGVyIDwtIGZhY3RvcihtdSRPcmRlciwNCiAgICAgICAgICAgICAgICAgICBsZXZlbCA9IHVsJE9yZGVyKQ0KbXUkdG90YWwgPC0gTlVMTA0KDQpkYXRhdGFibGUobXUsDQogICAgICAgICAgcm93bmFtZXMgPSBGQUxTRSwNCiAgICAgICAgICBjYXB0aW9uID0gIlRheG9ub21pYyAgY291bnQgdGFibGUiLA0KICAgICAgICAgIGNsYXNzID0gImNlbGwtYm9yZGVyIHN0cmlwZSIsDQogICAgICAgICAgb3B0aW9ucyA9IGxpc3Qoc2VhcmNoID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgICAgcGFnZUxlbmd0aCA9IDEwLA0KICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyID0gbGlzdChsaXN0KDMsICdkZXNjJykpKSkgJT4lDQogIGZvcm1hdEN1cnJlbmN5KGNvbHVtbnMgPSA1LA0KICAgICAgICAgICAgICAgICBjdXJyZW5jeSA9ICIiLA0KICAgICAgICAgICAgICAgICBtYXJrID0gIiwiLA0KICAgICAgICAgICAgICAgICBkaWdpdHMgPSAyKQ0KYGBgDQoNCmBgYHtyIG1lYW5zX29fcDAsIGZpZy53aWR0aCA9IDksIGZpZy5oZWlnaHQgPSA3fQ0KbXUkVHJ0X0dlbm90eXBlIDwtIGZhY3RvcihwYXN0ZShtdSRUcmVhdG1lbnQsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11JEdlbm90eXBlLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXAgPSAiXyIpKQ0KDQpwMCA8LSBnZ3Bsb3QobXUsDQogICAgICAgICAgICAgYWVzKHggPSBXZWVrLA0KICAgICAgICAgICAgICAgICB5ID0geCwNCiAgICAgICAgICAgICAgICAgZ3JvdXAgPSBUcnRfR2Vub3R5cGUpKSArDQogIGZhY2V0X3dyYXAofiBPcmRlciwNCiAgICAgICAgICAgICBzY2FsZSA9ICJmcmVlX3kiKSArDQogIGdlb21fbGluZShwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuMykpICsNCiAgZ2VvbV9wb2ludChhZXMoZmlsbCA9IFRydF9HZW5vdHlwZSksDQogICAgICAgICAgICAgc2hhcGUgPSAyMSwNCiAgICAgICAgICAgICBzaXplID0gMiwNCiAgICAgICAgICAgICBhbHBoYSA9IDAuNSwNCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuMykpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZSgiIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIlJlbGF0aXZlIEFidW5kYW5jZSAoJSkiKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLA0KICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoanVzdCA9IDEpKQ0KDQp0aWZmKGZpbGVuYW1lID0gInRtcC93dF9PcmRlcl9vdmVyX3RpbWUudGlmZiIsDQogICAgIGhlaWdodCA9IDUsDQogICAgIHdpZHRoID0gNywNCiAgICAgdW5pdHMgPSAiaW4iLA0KICAgICByZXMgPSA2MDAsDQogICAgIGNvbXByZXNzaW9uID0gImx6dytwIikNCnByaW50KHAwKQ0KZ3JhcGhpY3Mub2ZmKCkNCg0KcHJpbnQocDApDQpgYGANCg0KYGBge3IgbWVhbnNfb19wMSwgZmlnLmhlaWdodCA9IDUsIGZpZy53aWR0aCA9IDl9DQpwMSA8LSBnZ3Bsb3QobXUsDQogICAgICAgICAgICAgYWVzKHggPSB4LA0KICAgICAgICAgICAgICAgICB5ID0gT3JkZXIsDQogICAgICAgICAgICAgICAgIGNvbG9yID0gVHJ0X0dlbm90eXBlLA0KICAgICAgICAgICAgICAgICBzaGFwZSA9IFdlZWspKSArDQogIGdlb21fcG9pbnQoc2l6ZSA9IDMsDQogICAgICAgICAgICAgYWxwaGEgPSAwLjUpICsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMSwNCiAgICAgICAgICAgICBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIHNjYWxlX3hfY29udGludW91cygiUmVsYXRpdmUgQWJ1bmRhbmNlICglKSIpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpDQoNCnRpZmYoZmlsZW5hbWUgPSAidG1wL3d0X09yZGVyX3JhLnRpZmYiLA0KICAgICBoZWlnaHQgPSA0LA0KICAgICB3aWR0aCA9IDcsDQogICAgIHVuaXRzID0gImluIiwNCiAgICAgcmVzID0gNjAwLA0KICAgICBjb21wcmVzc2lvbiA9ICJsencrcCIpDQpwcmludChwMSkNCmdyYXBoaWNzLm9mZigpDQoNCmdncGxvdGx5KHAxKQ0KYGBgDQoNCiMjIDMuIEZhbWlseQ0KYGBge3IgY291bnRzX2YsIHdhcm5pbmc9RkFMU0UsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFLGZpZy53aWR0aD0xNSxmaWcuaGVpZ2h0PTE1fQ0KY291bnRzX2YgPC0gY291bnRzX2J5X3RheF9yYW5rKGR0MSA9IG90dTEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWdncl9ieSA9ICJGYW1pbHkiKQ0KcmFfZiA8LSByYV9ieV90YXhfcmFuayhjb3VudHNfZikNCg0KdGF4LnJhbmtzIDwtIHVuaXF1ZShvdHUxWywgYygiUGh5bHVtIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZhbWlseSIpXSkNCg0KcmFfZiA8LSBtZXJnZSh0YXgucmFua3MsDQogICAgICAgICAgICAgIHJhX2YsDQogICAgICAgICAgICAgIGJ5ID0gIkZhbWlseSIpDQoNCnRvdGFsIDwtIHJvd1N1bXMocmFfZlssIDM6bmNvbChyYV9mKV0pDQoNCnJhX2YkRmFtaWx5IDwtIGZhY3RvcihyYV9mJEZhbWlseSwNCiAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IHJhX2YkRmFtaWx5W29yZGVyKHRvdGFsKV0pDQoNCnJhX2YkUGh5bHVtIDwtIGZhY3RvcihyYV9mJFBoeWx1bSwNCiAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSB1bmlxdWUocmFfZiRQaHlsdW1bb3JkZXIodG90YWwpXSkpDQp0bXAgPC0gbWVsdC5kYXRhLnRhYmxlKGRhdGEgPSByYV9mLA0KICAgICAgICAgICAgICAgICAgICAgICBpZC52YXJzID0gMToyLA0KICAgICAgICAgICAgICAgICAgICAgICBtZWFzdXJlLnZhcnMgPSAzOm5jb2woY291bnRzX2YpLA0KICAgICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZS5uYW1lID0gIlNBTVBMRV9OQU1FIiwNCiAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUubmFtZSA9ICJSQSIpDQoNCnRtcCA8LSBtZXJnZShkYXRhLnRhYmxlKFNBTVBMRV9OQU1FID0gc21wbCRTQU1QTEVfTkFNRSwNCiAgICAgICAgICAgICAgICAgICAgICAgIFdFRUsgPSBzbXBsJFdFRUssDQogICAgICAgICAgICAgICAgICAgICAgICBUUkVBVE1FTlQgPSBzbXBsJFRSRUFUTUVOVCwNCiAgICAgICAgICAgICAgICAgICAgICAgIEdlbm90eXBlID0gc21wbCRHZW5vdHlwZSksDQogICAgICAgICAgICAgdG1wLA0KICAgICAgICAgICAgIGJ5ID0gIlNBTVBMRV9OQU1FIikNCg0KIyBQbG90IHNhbXBsZXMNCnAxIDwtIGdncGxvdCh0bXAsDQogICAgICAgICAgICAgYWVzKHggPSBTQU1QTEVfTkFNRSwNCiAgICAgICAgICAgICAgICAgeSA9IFJBLA0KICAgICAgICAgICAgICAgICBmaWxsID0gRmFtaWx5LA0KICAgICAgICAgICAgICAgICBjb2xvciA9IFBoeWx1bSkpICsNCiAgZmFjZXRfd3JhcCh+IFdFRUsgKyBUUkVBVE1FTlQgKyBHZW5vdHlwZSwNCiAgICAgICAgICAgICBzY2FsZXMgPSAiZnJlZV94IiwNCiAgICAgICAgICAgICBucm93ID0gMykgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKw0KICBzY2FsZV94X2Rpc2NyZXRlKCIiKSArDQogIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAsIDApKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGp1c3QgPSAxKSkNCmdncGxvdGx5KHAxKQ0KYGBgDQoNCmBgYHtyIG1lYW5zX2YsIGVjaG8gPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0V9DQpscmEgPC0gcmFfbWVsdChyYSA9IHJhX2YsDQogICAgICAgICAgICAgICBzYW1wbGVzID0gc21wbCwNCiAgICAgICAgICAgICAgIHNhbXBsZV9uYW1lID0gIlNBTVBMRV9OQU1FIikNCg0KbXUgPC0gZGF0YS50YWJsZShhZ2dyZWdhdGUobHJhJFJBLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgYnkgPSBsaXN0KFdlZWsgPSBscmEkV0VFSywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmVhdG1lbnQgPSBscmEkVFJFQVRNRU5ULA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdlbm90eXBlID0gbHJhJEdlbm90eXBlLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZhbWlseSA9IGxyYSRGYW1pbHkpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgRlVOID0gIm1lYW4iKSkNCm11WywgdG90YWwgOj0gc3VtKHgpLA0KICAgYnkgPSAiRmFtaWx5Il0NCnVsIDwtIHVuaXF1ZShtdVssIGMoIkZhbWlseSIsIA0KICAgICAgICAgICAgICAgICAgICAidG90YWwiKV0pDQp1bCA8LSB1bFtvcmRlcih0b3RhbCksXQ0KbXUkRmFtaWx5IDwtIGZhY3RvcihtdSRGYW1pbHksDQogICAgICAgICAgICAgICAgICAgbGV2ZWwgPSB1bCRGYW1pbHkpDQptdSR0b3RhbCA8LSBOVUxMDQoNCmRhdGF0YWJsZShtdSwNCiAgICAgICAgICByb3duYW1lcyA9IEZBTFNFLA0KICAgICAgICAgIGNhcHRpb24gPSAiVGF4b25vbWljICBjb3VudCB0YWJsZSIsDQogICAgICAgICAgY2xhc3MgPSAiY2VsbC1ib3JkZXIgc3RyaXBlIiwNCiAgICAgICAgICBvcHRpb25zID0gbGlzdChzZWFyY2ggPSBGQUxTRSwNCiAgICAgICAgICAgICAgICAgICAgICAgICBwYWdlTGVuZ3RoID0gMTAsDQogICAgICAgICAgICAgICAgICAgICAgICAgRmFtaWx5ID0gbGlzdChsaXN0KDMsICdkZXNjJykpKSkgJT4lDQogIGZvcm1hdEN1cnJlbmN5KGNvbHVtbnMgPSA1LA0KICAgICAgICAgICAgICAgICBjdXJyZW5jeSA9ICIiLA0KICAgICAgICAgICAgICAgICBtYXJrID0gIiwiLA0KICAgICAgICAgICAgICAgICBkaWdpdHMgPSAyKQ0KYGBgDQoNCk5PVEU6IG9ubHkgdGhlIGZpcnN0IDI0IGZhbWlsaWVzIGhhZCBsYXJnZSBlbm91Z2ggY291bnRzIC0gcGxvdGluZyBvbmx5IHRoZW0uICANCiAgDQpgYGB7ciBtZWFuc19mX3AwLCBmaWcud2lkdGggPSA5LCBmaWcuaGVpZ2h0ID0gN30NCm11JFRydF9HZW5vdHlwZSA8LSBmYWN0b3IocGFzdGUobXUkVHJlYXRtZW50LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdSRHZW5vdHlwZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VwID0gIl8iKSkNCm11MSA8LSBkcm9wbGV2ZWxzKG11W0ZhbWlseSAlaW4lIGxldmVscyhtdSRGYW1pbHkpW25sZXZlbHMobXUkRmFtaWx5KToobmxldmVscyhtdSRGYW1pbHkpIC0gMjQpXSwgXSkNCg0KcDAgPC0gZ2dwbG90KG11MSwNCiAgICAgICAgICAgICBhZXMoeCA9IFdlZWssDQogICAgICAgICAgICAgICAgIHkgPSB4LA0KICAgICAgICAgICAgICAgICBncm91cCA9IFRydF9HZW5vdHlwZSkpICsNCiAgZmFjZXRfd3JhcCh+IEZhbWlseSwNCiAgICAgICAgICAgICBzY2FsZSA9ICJmcmVlX3kiKSArDQogIGdlb21fbGluZShwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuMykpICsNCiAgZ2VvbV9wb2ludChhZXMoZmlsbCA9IFRydF9HZW5vdHlwZSksDQogICAgICAgICAgICAgc2hhcGUgPSAyMSwNCiAgICAgICAgICAgICBzaXplID0gMiwNCiAgICAgICAgICAgICBhbHBoYSA9IDAuNSwNCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuMykpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZSgiIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIlJlbGF0aXZlIEFidW5kYW5jZSAoJSkiKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLA0KICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoanVzdCA9IDEpKQ0KDQp0aWZmKGZpbGVuYW1lID0gInRtcC93dF9GYW1pbHlfb3Zlcl90aW1lLnRpZmYiLA0KICAgICBoZWlnaHQgPSA3LA0KICAgICB3aWR0aCA9IDksDQogICAgIHVuaXRzID0gImluIiwNCiAgICAgcmVzID0gNjAwLA0KICAgICBjb21wcmVzc2lvbiA9ICJsencrcCIpDQpwcmludChwMCkNCmdyYXBoaWNzLm9mZigpDQoNCnByaW50KHAwKQ0KYGBgDQoNCmBgYHtyIG1lYW5zX2ZfcDEsIGZpZy5oZWlnaHQgPSA1LCBmaWcud2lkdGggPSA5fQ0KcDEgPC0gZ2dwbG90KG11MSwNCiAgICAgICAgICAgICBhZXMoeCA9IHgsDQogICAgICAgICAgICAgICAgIHkgPSBGYW1pbHksDQogICAgICAgICAgICAgICAgIGNvbG9yID0gVHJ0X0dlbm90eXBlLA0KICAgICAgICAgICAgICAgICBzaGFwZSA9IFdlZWspKSArDQogIGdlb21fcG9pbnQoc2l6ZSA9IDMsDQogICAgICAgICAgICAgYWxwaGEgPSAwLjUpICsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMSwNCiAgICAgICAgICAgICBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIHNjYWxlX3hfY29udGludW91cygiUmVsYXRpdmUgQWJ1bmRhbmNlICglKSIpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpDQoNCnRpZmYoZmlsZW5hbWUgPSAidG1wL3d0X0ZhbWlseV9yYS50aWZmIiwNCiAgICAgaGVpZ2h0ID0gNCwNCiAgICAgd2lkdGggPSA3LA0KICAgICB1bml0cyA9ICJpbiIsDQogICAgIHJlcyA9IDYwMCwNCiAgICAgY29tcHJlc3Npb24gPSAibHp3K3AiKQ0KcHJpbnQocDEpDQpncmFwaGljcy5vZmYoKQ0KDQpnZ3Bsb3RseShwMSkNCmBgYA0KDQojIyA0LiBHZW51cw0KYGBge3IgY291bnRzX2csIHdhcm5pbmc9RkFMU0UsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFLGZpZy53aWR0aD0xNSxmaWcuaGVpZ2h0PTE1fQ0KY291bnRzX2cgPC0gY291bnRzX2J5X3RheF9yYW5rKGR0MSA9IG90dTEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWdncl9ieSA9ICJHZW51cyIpDQpyYV9nIDwtIHJhX2J5X3RheF9yYW5rKGNvdW50c19nKQ0KDQp0YXgucmFua3MgPC0gdW5pcXVlKG90dTFbLCBjKCJQaHlsdW0iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR2VudXMiKV0pDQoNCnJhX2cgPC0gbWVyZ2UodGF4LnJhbmtzLA0KICAgICAgICAgICAgICByYV9nLA0KICAgICAgICAgICAgICBieSA9ICJHZW51cyIpDQoNCnRvdGFsIDwtIHJvd1N1bXMocmFfZ1ssIDM6bmNvbChyYV9nKV0pDQoNCnJhX2ckR2VudXMgPC0gZmFjdG9yKHJhX2ckR2VudXMsDQogICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSByYV9nJEdlbnVzW29yZGVyKHRvdGFsKV0pDQoNCnJhX2ckUGh5bHVtIDwtIGZhY3RvcihyYV9nJFBoeWx1bSwNCiAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSB1bmlxdWUocmFfZyRQaHlsdW1bb3JkZXIodG90YWwpXSkpDQp0bXAgPC0gbWVsdC5kYXRhLnRhYmxlKGRhdGEgPSByYV9nLA0KICAgICAgICAgICAgICAgICAgICAgICBpZC52YXJzID0gMToyLA0KICAgICAgICAgICAgICAgICAgICAgICBtZWFzdXJlLnZhcnMgPSAzOm5jb2woY291bnRzX2cpLA0KICAgICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZS5uYW1lID0gIlNBTVBMRV9OQU1FIiwNCiAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUubmFtZSA9ICJSQSIpDQoNCnRtcCA8LSBtZXJnZShkYXRhLnRhYmxlKFNBTVBMRV9OQU1FID0gc21wbCRTQU1QTEVfTkFNRSwNCiAgICAgICAgICAgICAgICAgICAgICAgIFdFRUsgPSBzbXBsJFdFRUssDQogICAgICAgICAgICAgICAgICAgICAgICBUUkVBVE1FTlQgPSBzbXBsJFRSRUFUTUVOVCwNCiAgICAgICAgICAgICAgICAgICAgICAgIEdlbm90eXBlID0gc21wbCRHZW5vdHlwZSksDQogICAgICAgICAgICAgdG1wLA0KICAgICAgICAgICAgIGJ5ID0gIlNBTVBMRV9OQU1FIikNCg0KIyBQbG90IHNhbXBsZXMNCnAxIDwtIGdncGxvdCh0bXAsDQogICAgICAgICAgICAgYWVzKHggPSBTQU1QTEVfTkFNRSwNCiAgICAgICAgICAgICAgICAgeSA9IFJBLA0KICAgICAgICAgICAgICAgICBmaWxsID0gR2VudXMsDQogICAgICAgICAgICAgICAgIGNvbG9yID0gUGh5bHVtKSkgKw0KICBmYWNldF93cmFwKH4gV0VFSyArIFRSRUFUTUVOVCArIEdlbm90eXBlLA0KICAgICAgICAgICAgIHNjYWxlcyA9ICJmcmVlX3giLA0KICAgICAgICAgICAgIG5yb3cgPSAzKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArDQogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwgMCkpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoanVzdCA9IDEpKQ0KZ2dwbG90bHkocDEpDQpgYGANCg0KDQpgYGB7ciBtZWFuc19nLCBlY2hvID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFfQ0KbHJhIDwtIHJhX21lbHQocmEgPSByYV9nLA0KICAgICAgICAgICAgICAgc2FtcGxlcyA9IHNtcGwsDQogICAgICAgICAgICAgICBzYW1wbGVfbmFtZSA9ICJTQU1QTEVfTkFNRSIpDQoNCm11IDwtIGRhdGEudGFibGUoYWdncmVnYXRlKGxyYSRSQSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5ID0gbGlzdChXZWVrID0gbHJhJFdFRUssDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHJlYXRtZW50ID0gbHJhJFRSRUFUTUVOVCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZW5vdHlwZSA9IGxyYSRHZW5vdHlwZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZW51cyA9IGxyYSRHZW51cyksDQogICAgICAgICAgICAgICAgICAgICAgICAgICBGVU4gPSAibWVhbiIpKQ0KbXVbLCB0b3RhbCA6PSBzdW0oeCksDQogICBieSA9ICJHZW51cyJdDQp1bCA8LSB1bmlxdWUobXVbLCBjKCJHZW51cyIsIA0KICAgICAgICAgICAgICAgICAgICAidG90YWwiKV0pDQp1bCA8LSB1bFtvcmRlcih0b3RhbCksXQ0KbXUkR2VudXMgPC0gZmFjdG9yKG11JEdlbnVzLA0KICAgICAgICAgICAgICAgICAgIGxldmVsID0gdWwkR2VudXMpDQptdSR0b3RhbCA8LSBOVUxMDQoNCmRhdGF0YWJsZShtdSwNCiAgICAgICAgICByb3duYW1lcyA9IEZBTFNFLA0KICAgICAgICAgIGNhcHRpb24gPSAiVGF4b25vbWljICBjb3VudCB0YWJsZSIsDQogICAgICAgICAgY2xhc3MgPSAiY2VsbC1ib3JkZXIgc3RyaXBlIiwNCiAgICAgICAgICBvcHRpb25zID0gbGlzdChzZWFyY2ggPSBGQUxTRSwNCiAgICAgICAgICAgICAgICAgICAgICAgICBwYWdlTGVuZ3RoID0gMTAsDQogICAgICAgICAgICAgICAgICAgICAgICAgR2VudXMgPSBsaXN0KGxpc3QoMywgJ2Rlc2MnKSkpKSAlPiUNCiAgZm9ybWF0Q3VycmVuY3koY29sdW1ucyA9IDUsDQogICAgICAgICAgICAgICAgIGN1cnJlbmN5ID0gIiIsDQogICAgICAgICAgICAgICAgIG1hcmsgPSAiLCIsDQogICAgICAgICAgICAgICAgIGRpZ2l0cyA9IDIpDQpgYGANCg0KYGBge3IgbWVhbnNfZ19wMCwgZmlnLndpZHRoID0gOSwgZmlnLmhlaWdodCA9IDd9DQptdSRUcnRfR2Vub3R5cGUgPC0gZmFjdG9yKHBhc3RlKG11JFRyZWF0bWVudCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXUkR2Vub3R5cGUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcCA9ICJfIikpDQptdTEgPC0gZHJvcGxldmVscyhtdVtHZW51cyAlaW4lIGxldmVscyhtdSRHZW51cylbbmxldmVscyhtdSRHZW51cyk6KG5sZXZlbHMobXUkR2VudXMpIC0gMzUpXSwgXSkNCg0KcDAgPC0gZ2dwbG90KG11MSwNCiAgICAgICAgICAgICBhZXMoeCA9IFdlZWssDQogICAgICAgICAgICAgICAgIHkgPSB4LA0KICAgICAgICAgICAgICAgICBncm91cCA9IFRydF9HZW5vdHlwZSkpICsNCiAgZmFjZXRfd3JhcCh+IEdlbnVzLA0KICAgICAgICAgICAgIHNjYWxlID0gImZyZWVfeSIpICsNCiAgZ2VvbV9saW5lKHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC4zKSkgKw0KICBnZW9tX3BvaW50KGFlcyhmaWxsID0gVHJ0X0dlbm90eXBlKSwNCiAgICAgICAgICAgICBzaGFwZSA9IDIxLA0KICAgICAgICAgICAgIHNpemUgPSAyLA0KICAgICAgICAgICAgIGFscGhhID0gMC41LA0KICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC4zKSkgKw0KICBzY2FsZV94X2Rpc2NyZXRlKCIiKSArDQogIHNjYWxlX3lfY29udGludW91cygiUmVsYXRpdmUgQWJ1bmRhbmNlICglKSIpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIsDQogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhqdXN0ID0gMSkpDQoNCnRpZmYoZmlsZW5hbWUgPSAidG1wL3d0X0dlbnVzX292ZXJfdGltZS50aWZmIiwNCiAgICAgaGVpZ2h0ID0gOSwNCiAgICAgd2lkdGggPSAxMiwNCiAgICAgdW5pdHMgPSAiaW4iLA0KICAgICByZXMgPSA2MDAsDQogICAgIGNvbXByZXNzaW9uID0gImx6dytwIikNCnByaW50KHAwKQ0KZ3JhcGhpY3Mub2ZmKCkNCg0KcHJpbnQocDApDQpgYGANCg0KYGBge3IgbWVhbnNfZ19wMSwgZmlnLmhlaWdodCA9IDksIGZpZy53aWR0aCA9IDl9DQpwMSA8LSBnZ3Bsb3QobXUxLA0KICAgICAgICAgICAgIGFlcyh4ID0geCwNCiAgICAgICAgICAgICAgICAgeSA9IEdlbnVzLA0KICAgICAgICAgICAgICAgICBjb2xvciA9IFRydF9HZW5vdHlwZSwNCiAgICAgICAgICAgICAgICAgc2hhcGUgPSBXZWVrKSkgKw0KICBnZW9tX3BvaW50KHNpemUgPSAzLA0KICAgICAgICAgICAgIGFscGhhID0gMC41KSArDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDEsDQogICAgICAgICAgICAgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoIlJlbGF0aXZlIEFidW5kYW5jZSAoJSkiKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKQ0KDQp0aWZmKGZpbGVuYW1lID0gInRtcC93dF9HZW51c19yYS50aWZmIiwNCiAgICAgaGVpZ2h0ID0gOSwNCiAgICAgd2lkdGggPSA5LA0KICAgICB1bml0cyA9ICJpbiIsDQogICAgIHJlcyA9IDYwMCwNCiAgICAgY29tcHJlc3Npb24gPSAibHp3K3AiKQ0KcHJpbnQocDEpDQpncmFwaGljcy5vZmYoKQ0KDQpnZ3Bsb3RseShwMSkNCmBgYA0KDQoNCg0KIyBTZXNzaW9uIEluZm9ybWF0aW9uDQpgYGB7ciBpbmZvLGV2YWw9VFJVRX0NCnNlc3Npb25JbmZvKCkNCmBgYA==